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   ,尝试调度成功。

 

posted @ 2021-09-11 17:08  颜小雀  阅读(156)  评论(0编辑  收藏  举报