linux内核中创建线程方法
生活随笔
收集整理的這篇文章主要介紹了
linux内核中创建线程方法
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1.頭文件
#include <linux/sched.h> //wake_up_process() #include <linux/kthread.h> //kthread_create()、kthread_run() #include <err.h> //IS_ERR()、PTR_ERR()2.實現(xiàn)(kthread_create 與kthread_run區(qū)別)
linux內(nèi)核創(chuàng)建線程的方法實質(zhì)上只有一個:kthread_create,kthread_run是kthread_create的宏罷了;但這個宏卻有一定的意義,正如其名一樣:
kthread_create:創(chuàng)建線程。線程創(chuàng)建后,不會馬上運行,而是需要將kthread_create()返回的task_struct指針傳給wake_up_process(),然后通過此函數(shù)運行線程。
kthread_run:創(chuàng)建并啟動線程的函數(shù):
2.1創(chuàng)建線程
在模塊初始化時,可以進(jìn)行線程的創(chuàng)建。使用下面的函數(shù)和宏定義:
struct task_struct *kthread_create(int (*threadfn)(void *data),
void *data,
const char namefmt[], ...);
#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線程函數(shù)
在線程函數(shù)里,完成所需的業(yè)務(wù)邏輯工作。主要框架如下所示:
int threadfunc(void *data){
…
while(1){
set_current_state(TASK_UNINTERRUPTIBLE);
if(kthread_should_stop()) break;
if(){//條件為真
//進(jìn)行業(yè)務(wù)處理
}
else{//條件為假
//讓出CPU運行其他線程,并在指定的時間內(nèi)重新被調(diào)度
schedule_timeout(HZ);
}
}
…
return 0;
}
2.3結(jié)束線程
在模塊卸載時,可以結(jié)束線程的運行。使用下面的函數(shù):
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) 在調(diào)用kthread_stop函數(shù)時,線程函數(shù)不能已經(jīng)運行結(jié)束。否則,kthread_stop函數(shù)會一直進(jìn)行等待。
(2) 線程函數(shù)必須能讓出CPU,以便能運行其他線程。同時線程函數(shù)也必須能重新被調(diào)度運行。在例子程序中,這是通過schedule_timeout()函數(shù)完成的。
4.性能測試
可以使用top命令來查看線程(包括內(nèi)核線程)的CPU利用率。命令如下:
top –p 線程號
可以使用下面命令來查找線程號:
ps aux|grep 線程名
可以用下面的命令顯示所有內(nèi)核線程:
ps afx
注:線程名由kthread_create函數(shù)的第三個參數(shù)指定
在分析usb_hub_init()的代碼的時候,忽略掉了一部份.
代碼片段如下所示:
int usb_hub_init(void)
{
……
khubd_task = kthread_run(hub_thread, NULL, "khubd");
……
}
Kthread_run() 是kernel中用來啟動一個新kernel線程的接口,它所要執(zhí)行的函數(shù)就是后面跟的第一個參數(shù).在這里,也就是hub_thread().另外,順帶 提一句,要終止kthread_run()創(chuàng)建的線程,可以調(diào)用kthread_stop().
總結(jié)
以上是生活随笔為你收集整理的linux内核中创建线程方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FPGA的EPCS 配置的2种方法 FP
- 下一篇: 拍胸片挂什么科