内核线程简介:
函数定义在include/linux/kthread.h中:
struct task_struct kthread_run(int (*threadfn)(void *data), void *data,constchar namefmt[],...);
int kthread_stop(struct task_struct *k);
int kthread_should_stop(void);
**kthread_run()**负责内核线程的创建并运行,参数包括回调函数名 threadfn,参数data,创建的内核线程名称namefmt。当然你会发现kthread_run()实际是一个宏定义,它由kthread_create()和wake_up_process() 两部分组成,其中kthread_create()只是创建一个内核线程,但并没有运行,还需要调用wake_up_process()来启动线程。所以我们这里只用调用kthread_run()就可以实现内核线程的创建并运行。内核线程创建成功后,会返回一个struct task_struct对象指针,方便我们的后续操作。
**kthread_stop(struct task_struct *k)**负责结束创建的内核线程,kthread_stop()发送should_stop标志给内核线程。kthread_stop()参数是创建内核线程时返回的struct task_struct指针,返回值是内核线程的返回值。kthread_stop()会阻塞等待,直到内核线程k退出为止。
kthread_should_stop()在kthread_stop()发送should_stop标志后的返回值为1,否则返回值为0。内核线程根据kthread_should_stop()的返回值来决定是否退出内核线程,以保证在调用kthread_stop()前,内核线程没有退出(我们需要保证在调用kthread_stop()时,内核线程没有退出,否则一调kthread_stop()就用会使程序crash!!!)。
例子:
#include <linux/kthread.h>
static struct task_struct * _task = NULL;
static struct task_struct * _task2 = NULL;
static int thread_func(void *data) //线程函数
{
printk("thread_func started\n");
while(!kthread_should_stop()) //在调用kthread_stop()后kthread_should_stop()返回1,否则返回值是0
{
printk("等待kthread_stop()被调用\n");
}
return 0;
}
void start_thread(void)
{
//_task = kthread_create(thread_func, NULL, "thread_func2");
//wake_up_process(_task);
_task = kthread_run(thread_func, NULL, "thread_func2"); //回调函数名;传给回调函数的数据指针;创建的这个内核线程的名字;
_task2 = kthread_run(thread_func, NULL, "thread_func2");
if (!_task)
{
printk("kthread_create error\n");
}
}
void end_thread(void)
{
int ret = 0;
ret = kthread_stop(_task); //阻塞等待线程退出(该函数会使kthread_should_stop()返回1,从而使线程退出);
_task = NULL;
printk("内核线程返回值为: %d\n" , ret);
ret = kthread_stop(_task2);
_task2 = NULL;
printk("内核线程返回值为: %d\n" , ret);
}