5

我是内核模块编程的新手,对于我的工作,我需要编写一个多线程内核模块。所以我尝试了内核线程的一些主要用途。我写了以下内容。它应该在一个线程中打印 1 个,在另一个线程中打印 2 个,均为 10 次。

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/udp.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/kthread.h>

struct task_struct *task1;
struct task_struct *task2;


static void thread_func(void* data)
{   
    int *n;
    n = (int *)data;
    int i = 0;
    while(i < 10){
        printk("%d\n", *n);
        i++;
    }
    //do_exit();
}

static int t_start(void)
{
    printk("Module starting ... ... ..\n");
    int *p1, *p2;
    int one = 1, two = 2;
    p1 = &one;
    p2 = &two;
    task1 = kthread_run(&thread_func, (void*)p1, "thread_func_1");
    task2 = kthread_run(&thread_func, (void*)p2, "thread_func_2");
    return 0;
}

static void t_end (void)
{
    printk("Module terminating ... ... ...\n");
    kthread_stop(task1);
    kthread_stop(task2);
}

module_init(t_start);
module_exit(t_end);

MODULE_AUTHOR("Md. Taufique Hussain");
MODULE_DESCRIPTION("Testing kernel threads");
MODULE_LICENSE("GPL");

但我面临以下问题。-

  1. 第一个线程正在打印所有十个 1,然后第二个线程正在执行。我想以交错的方式运行这两个。
  2. 第一个线程打印所有 1 都可以,但第二个线程不打印 2。它正在打印 0。可能参数没有正确传递给第二个线程。
  3. 当我插入模块时它正在运行但是当我移除模块时机器挂起

有什么问题?我该如何解决它们。

4

3 回答 3

3
  1. 你需要 schedule() 除非你有一个可抢占的内核和一些睡眠。
  2. 您正在从堆栈传递数据指针,从而破坏内核内存。使这些整数成为全局变量。
于 2012-10-19T12:51:38.697 回答
3

1.不要使用这些代码,删除它们

// kthread_stop(task1);
// kthread_stop(task2);

好像线程终止后,task会被设置为null,然后调用kthread_stop()会导致空指针错误

2.不要将局部变量传递给线程,而是使用全局变量。

3.如果你想让两个线程相互切换,使用“wait_event”和“wake_up”函数。这是我的工作代码。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/wait.h>

MODULE_LICENSE("GPL");


int pid1 = 1;
int pid2 = 2;

DECLARE_WAIT_QUEUE_HEAD(wq);

int condition;

struct task_struct *task1;
struct task_struct *task2;

static int thread_function(void *data){

    int *thread_id = (int*)data;
    int i = 0;
    while(i < 10){
       printk(KERN_INFO "install kernel thread: %d\n", *thread_id);
       i++;

       if(*thread_id == 1)
       {
            wait_event(wq, condition == 0xA);

            condition = 0xB;
            wake_up(&wq);
       }
       else{
            wait_event(wq, condition == 0xB);

            condition = 0xA;
            wake_up(&wq);
       }
   }
   return 0;
}


static int kernel_init(void)
{
     condition = 0xA;

     task1 = kthread_create(&thread_function, (void *)&pid1, "pradeep");
     task2 = kthread_create(&thread_function, (void *)&pid2, "pradeep"); 

     //printk(KERN_INFO "After create kernel thread\n");
     wake_up_process(task1);
     wake_up_process(task2);
     return 0;
}

int init_module(void)
{
    kernel_init();
    return 0;
}

void cleanup_module(void)
{
    return;
}

‍</p>

于 2015-01-27T19:18:59.563 回答
2

添加schedule调用以强制线程调度。

static void thread_func(void* data)
{   
    int *n;
    n = (int *)data;
    int i = 0;
    while(i < 10){
        printk("%d\n", *n);

        schedule();

        i++;
    }
    //do_exit();
}
于 2012-10-19T12:27:31.200 回答