头文件:
#include <linux/sched.h> //wake_up_process()
#include <linux/kthread.h> //kthread_create()、kthread_run()
#include <err.h> //IS_ERR()、PTR_ERR()
1.创建并启动一个内核线程:
方式一:
struct task_struct *
kthread_create( int (*threadfn(void *data),void *data,const char *namefmt, ... );
线程创建后,不会马上运行,而是需要将kthread_create() 返回的task_struct指针传给wake_up_process(),然后通过此函数运行线程。
方式二:
kthread_run :创建并启动线程的函数:
struct task_struct *
kthread_run(int (*threadfn)(void *data),void *data,const char *namefmt, ...);
2.停止线程:
kthread_stop:通过发送信号给线程,使之退出。
int kthread_stop(struct task_struct *thread);
线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用kthread_stop函数,结束线程的运行。
但如果线程函数正在处理一个非常重要的任务,它不会被中断的。当然如果线程函数永远不返回并且不检查信号,它将永远都不会停止
kthread_should_stop函数,我们需要在开启的线程中嵌入该函数并检查此函数的返回值,否则kthread_stop是不起作用的
msleep_interruptible() //延时函数
Schedule_timeout_interruptible
Schedule_timeout_uninterruptible
Schedule_timeout_killable
Schedule_timeout
更理想的延迟执行方法是使用schedule_timeout()函数,该方法会让需要延迟的任务睡眠到指定的延迟时间耗尽后再重新运行。但该方法也不能保证睡眠时间正好等于指定的延迟时间,只能尽量使睡眠时间接近指定的延迟时间。当指定的时间到期后,内核唤醒被延迟的任务并将其重新放回运行队列,用法如下:
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(s*hz);
唯一的参数是延迟的相对时间,单位为jiffies,上列中将相应的任务推入可中断睡眠队列,睡眠s秒。因为任务处于可中断状态,所以如果任务收到信号将被唤醒。如果睡眠任务不想接受信号,可以将任务状态设置为TASK_UNINTERRUPTIBLE,然后睡眠。注意,在调用schedule_timeout()函数前必须首先将任务设置成上面两种状态之一,否则任务不会睡眠。
注意,由于schedule_timeout()函数需要调度程序,所以调用它的代码必须保证能够睡眠。简而言之,调用代码必须处于进程上下文中,并且不能持有锁
标签:kthread,睡眠,函数,线程,内核,timeout,linux,struct From: https://blog.csdn.net/ghx19940812/article/details/145209253