linux内核中创建线程方法

1.头文件

#include <linux/sched.h>   //wake_up_process()

#include <linux/kthread.h>//kthread_create()kthread_run()

#include <err.h>//IS_ERR()PTR_ERR()

 

2.实现(kthread_create kthread_run区别)

linux内核创建线程的方法实质上只有一个:kthread_createkthread_runkthread_create的宏罢了;但这个宏却有一定的意义,正如其名一样:

kthread_create:创建线程。线程创建后,不会马上运行,而是需要将kthread_create() 返回的task_struct指针传给wake_up_process(),然后通过此函数运行线程。

kthread_run :创建并启动线程的函数:

 

2.1创建线程

在模块初始化时,可以进行线程的创建。使用下面的函数和宏定义:

struct task_struct *kthread_create(int(*threadfn)(void *data),

                            void *data,

                            const charnamefmt[], ...);

 

#define kthread_run(threadfn, data,namefmt, ...)                     \

({                                                           \

   struct task_struct *__k                                        \

          = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \

   if (!IS_ERR(__k))                                        \

          wake_up_process(__k);                                \

   __k;                                                    \

})

 

 

 

例如:

 

static struct task_struct *test_task;

static int test_init_module(void)

{

   int err;

   test_task = kthread_create(test_thread, NULL, "test_task");

   if(IS_ERR(test_task)){

     printk("Unable to start kernel thread. ");

     err = PTR_ERR(test_task);

     test_task = NULL;

     return err;

    }

wake_up_process(test_task);

      return 0;

   }

module_init(test_init_module);

 

2.2线程函数

在线程函数里,完成所需的业务逻辑工作。主要框架如下所示:

int threadfunc(void *data){

       …

while(1){

set_current_state(TASK_UNINTERRUPTIBLE);

if(kthread_should_stop()) break;

if(){//条件为真

//进行业务处理

}

else{//条件为假

//让出CPU运行其他线程,并在指定的时间内重新被调度

schedule_timeout(HZ);

}

}

return 0;

}

 

 

2.3结束线程

在模块卸载时,可以结束线程的运行。使用下面的函数:

int kthread_stop(struct task_struct *k);

例如:

static void test_cleanup_module(void)

{

if(test_task){

kthread_stop(test_task);

test_task = NULL;

}

}

module_exit(test_cleanup_module);

 

3.注意事项

1)在调用kthread_stop函数时,线程函数不能已经运行结束。否则,kthread_stop函数会一直进行等待。

2)线程函数必须能让出CPU,以便能运行其他线程。同时线程函数也必须能重新被调度运行。在例子程序中,这是通过schedule_timeout()函数完成的。


4.性能测试

可以使用top命令来查看线程(包括内核线程)的CPU利用率。命令如下:

top p 线程号

可以使用下面命令来查找线程号:

ps aux|grep 线程名

可以用下面的命令显示所有内核线程:

ps afx

注:线程名由kthread_create函数的第三个参数指定

 

在分析usb_hub_init()的代码的时候,忽略掉了一部份.

代码片段如下所示:

int usb_hub_init(void)

{

……

khubd_task = kthread_run(hub_thread, NULL,"khubd");

……

}

Kthread_run() kernel中用来启动一个新kernel线程的接口,它所要执行的函数就是后面跟的第一个参数.在这里,也就是hub_thread().另外,顺带提一句,要终止kthread_run()创建的线程,可以调用kthread_stop().

640?wx_fmt=jpeg


  • 0
    点赞
  • 0
    评论
  • 10
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值