Linux tasklet 的测试
在看 内核代码的时候 发现 tasklet 的 api ,想着如何去使用它。
首先是 tasklet_disable 和 tasklet_kill 的 区别
测试demo 如下:
#include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/kobject.h> #include <linux/list.h> #include <linux/kthread.h> #include <asm/ptrace.h> #include <linux/sched.h> #include <linux/delay.h> #include <linux/interrupt.h> int data = 10; void tasklet_func(unsigned long data) { printk(KERN_INFO "tasklet_func \r\n"); } struct tasklet_struct tasklet; int threadfn(void *data) { static int count = 0 ; int args = *(int *)data; printk(KERN_INFO "enter thead_fn"); while(1) { msleep(2*1000); printk(KERN_INFO "threadfn data: %d, count: %d\r\n",args , ++count); if(count == 3) { printk(KERN_INFO "tasklet_kill \r\n"); tasklet_kill(&tasklet); } else { printk(KERN_INFO "-----------\r\n"); tasklet_schedule(&tasklet); } } } //模块初始化函数 static int __init test_kobj_init(void) { tasklet_init(&tasklet,tasklet_func,data); struct task_struct * thread = kthread_create( threadfn,(void * )&data,"mythread"); if(thread != NULL) { printk(KERN_INFO "thread create success\r\n"); wake_up_process(thread); }else { printk(KERN_ERR "thread create err\r\n"); } return 0; } //模块清理函数 static void __exit test_kobj_exit(void) { printk(KERN_INFO "test_kobj_exit \r\n"); return; } module_init(test_kobj_init); module_exit(test_kobj_exit); MODULE_AUTHOR("LoyenWang"); MODULE_LICENSE("GPL");
我一开始的设想是 调用了tasklet_kill函数之后 ,以后的调用都不会出现 tasklet_func .
但是实际情况却是如此。
当 count == 3 时候 我没有去调度 ,所以 func 没有打印很正常 ,但是 再下一个再次使用 tasklet_schedule 时候 ,依然可以有打印出来 ,
所以 tasklet_kill 不会影响 tasklet_schedule 的调度。
于是测试 demo2
#include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/kobject.h> #include <linux/list.h> #include <linux/kthread.h> #include <asm/ptrace.h> #include <linux/sched.h> #include <linux/delay.h> #include <linux/interrupt.h> int data = 10; void tasklet_func(unsigned long data) { printk(KERN_INFO "tasklet_func \r\n"); } struct tasklet_struct tasklet; int threadfn(void *data) { static int count = 0 ; int args = *(int *)data; printk(KERN_INFO "enter thead_fn"); while(1) { msleep(2*1000); printk(KERN_INFO "threadfn data: %d, count: %d\r\n",args , ++count); if(count == 3) { printk(KERN_INFO "tasklet_kill \r\n"); tasklet_disable(&tasklet); }else if (count == 5) { printk(KERN_INFO " tasklet_enable \r\n"); tasklet_enable(&tasklet); } else { printk(KERN_INFO "-----------\r\n"); tasklet_schedule(&tasklet); } } } //模块初始化函数 static int __init test_kobj_init(void) { tasklet_init(&tasklet,tasklet_func,data); struct task_struct * thread = kthread_create( threadfn,(void * )&data,"mythread"); if(thread != NULL) { printk(KERN_INFO "thread create success\r\n"); wake_up_process(thread); }else { printk(KERN_ERR "thread create err\r\n"); } return 0; } //模块清理函数 static void __exit test_kobj_exit(void) { printk(KERN_INFO "test_kobj_exit \r\n"); return; } module_init(test_kobj_init); module_exit(test_kobj_exit); MODULE_AUTHOR("LoyenWang"); MODULE_LICENSE("GPL");
就是在 count == 3 时候 , 使用tasklet_disable ,在count == 4 时候 ,尝试调度 ,在count ==5 时候,tasklet_enable ,接着之后尝试调度。
现象如下:
发现 在使用了 tasklet_disable 之后 ,尝试调度 会失效 , 当再次 tasklet_enable ,尝试调度成功。