一、kthread_create & kthread_run 内核线程是工作在内核空间的,不属于任何一个进程,可以发生睡眠。可以用内核线程来进行一些循环的动作,比如通过循环拉高拉低gpio设置成方波输出的信号来模拟pwm信号,比如循环控制led的闪灯效果等等都可以使用到内核线程kthread_create接口函数。
内核线程的相关代码目录:
1 2 include/linux/kthread.h kernel/kthread.c
创建并启动一个内核线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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; \ })
其中kthread_create()只是创建一个内核线程,但并没有启动,需要调用wake_up_process()来启动线程,所以内核又帮我们定义了一个宏kthread_run来帮我们搞定。内核线程创建成功后,会返回一个struct task_struct对象指针,方便我们的后续操作。
二、关闭一个内核线程 1 int kthread_stop (struct task_struct *k) ;
这个调用是会阻塞等待,直到内核线程k退出为止。原因为此函数内部会调用wait_for_completion()的方法(通过等待队列来实现),阻塞等待内核线程自身的退出。
三、内核线程函数,如何判断自身需要退出 1 int kthread_should_stop (void ) ;
如果该内核线程已经被设置stop标志了,则会返回1,否则返回0。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <linux/module.h> #include <linux/kthread.h> #include <linux/delay.h> #define ENTER() printk(KERN_DEBUG "%s() Enter" , __func__) #define EXIT() printk(KERN_DEBUG "%s() Exit" , __func__) #define ERR(fmt, args...) printk(KERN_ERR "%s()-%d: " fmt "\n" , __func__, __LINE__, ##args) #define DBG(fmt, args...) printk(KERN_DEBUG "%s()-%d: " fmt "\n" , __func__, __LINE__, ##args) static struct task_struct *test_kthread = NULL ; static int kthread_test_func (void ) { ENTER(); while (!kthread_should_stop()) { DBG("kthread is running" ); msleep(5000 ); } EXIT(); return 0 ; }static __init int kthread_test_init (void ) { ENTER(); test_kthread = kthread_run(kthread_test_func, NULL , "kthread-test" ); _ if (!test_kthread) { ERR("kthread_run fail" ); return -ECHILD; } EXIT(); return 0 ; }static __exit void kthread_test_exit (void ) { ENTER(); if (test_kthread) { DBG("kthread_stop" ); kthread_stop(test_kthread); _ test_kthread = NULL ; } EXIT(); } module_init(kthread_test_init); module_exit(kthread_test_exit); MODULE_AUTHOR("czd,214241976@qq.com" ); MODULE_DESCRIPTION("Device_create Driver" ); MODULE_LICENSE("GPL" );