三白草

首页 » 常识 » 预防 » 创建Linux内核线程
TUhjnbcbe - 2021/1/30 5:14:00

线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每个线程并行执行不同的任务。

很多时候会需要在后台执行一些任务,比如做一个需要实时监控某个模块状态的debug功能,这种任务可以通过内核线程实现。

头文件

//wake_up_process()#includelinux/sched.h//kthread_create(),kthread_run()#includelinux/kthread.h//IS_ERR()、PTR_ERR()#includelinux/err.h

操作线程的步骤:

1.创建线程kthread_create

2.唤醒线程wake_up_process

3.结束线程kthread_stop

*另外Linux也提供了接口kthread_run将1和2整合成一个步骤。

创建线程kthread_create

kthread_create是kthread_create_on_node的宏定义,创建线程后不会马上运行,其源码如下:

#definekthread_create(threadfn,data,namefmt,arg...)\kthread_create_on_node(threadfn,data,NUMA_NO_NODE,namefmt,##arg)

kthread_create_on_node的定义在文件kernel/kthread.c中,原型如下:

__printf(4,5)structtask_struct*kthread_create_on_node(int(*threadfn)(void*data),void*data,intnode,constcharnamefmt[],...);

参数说明

threadfn:线程函数,即开启线程后需要call的API;

data:线程函数的形参,可以是NULL;

namefmt:线程名称;

返回值:线程指针strcuttask_struct*;

唤醒线程wake_up_process

使用kthread_create创建线程后,需要将返回值

(structtask_struct*)作为参数传入wake_up_process()将线程唤醒,线程才会跑起来,原型:

externintwake_up_process(structtask_struct*tsk);

创建并运行线程kthread_run

kthread_run是将kthread_create以及wake_up_process整合的宏定义,创建线程并运行,源码如下:

#definekthread_run(threadfn,data,namefmt,...)\({\structtask_struct*__k\=kthread_create(threadfn,data,namefmt,##__VA_ARGS__);\if(!IS_ERR(__k))\wake_up_process(__k);\__k;\})

结束线程kthread_stop

将创建线程时返回的线程指针(structtask_struct*)作为参数传入kthread_stop(),设置结束标志should_stop,原型:

intkthread_stop(structtask_struct*k);

在线程中用到的其他API

set_freezable()//将线程设置成可冻结,如果系统会休眠,则需要使用kthread_should_stop()//检查线程的结束标志should_stop并返回set_current_state()//设置线程任务的当前状态,参数宏定义在头文件include/linux/sched.h中

创建线程实例

LunuxMemo_kthread.c

#includelinux/kernel.h#includelinux/module.h#includelinux/sched.h//wake_up_process()#includelinux/kthread.h//kthread_create(),kthread_run()#includelinux/err.h//IS_ERR()、PTR_ERR()#defineCREATE_KTHREAD1#defineSTOP_KTHREAD0//kthreadtaskvoidLinuxMemo_kthread_task(void){printk(KERN_EMERG"PlzFollowWechatAccount:LinuxMemo\n");/**AddYOURcodehere*/}//kthreadfunctionintLinuxMemo_thread_func(void*data){char*name=(char*)data;//name="LinuxMemo"printk(KERN_EMERG"PlzFollowWechatAccount:%s\n",name);set_freezable();//setkthreadfreezablewhile(!kthread_should_stop()){LinuxMemo_kthread_task();}return0;}//CreateorstopakthreadintLinuxMemo_kthread_set(intset){char*name="LinuxMemo";staticstructtask_struct*LinuxMemo_kthread;if(CREATE_KTHREAD==set){//createandwakeupakthreadLinuxMemo_kthread=kthread_create(LinuxMemo_thread_func,(void*)name,"LinuxMemo_kthread");if(IS_ERR(LinuxMemo_task)){printk(KERN_EMERG"[%s]createLinuxMemo_kthreaderror\n",__func__);err=PTR_ERR(LinuxMemo_kthread);LinuxMemo_kthread=NULL;returnerr;}wake_up_process(LinuxMemo_task);printk(KERN_EMERG"[%s]LinuxMemo_kthreadstart\n",__func__);}elseif(STOP_KTHREAD==set){if(LinuxMemo_kthread){//Stopakthreadif(0==kthread_stop(LinuxMemo_kthread)){printk(KERN_EMERG"[%s]LinuxMemo_kthreadstop\n",__func__);}else{printk(KERN_EMERG"[%s]LinuxMemo_kthreadstoperror\n",__func__);}LinuxMemo_task=NULL;}}return0;}AnonymousCoward

1
查看完整版本: 创建Linux内核线程