工作队列

转自:http://blog.csdn.net/yoveldf/article/details/23916153

参考:http://blog.chinaunix.net/uid-26675482-id-3265027.html


1 "工作队列"用途

 工作队列用途跟tasklet相似,在中断处理时 将一些非紧急的任务留到工作队列中完成,而紧急的任务则在硬中断服务程序中完成。
 但工作队列与tasklet还是有很大的区别:
 1)工作队列函数在一个特殊内核进程的上下文中运行;
 2)tasklet会在很短的时间段内很快执行,且以原子模式执行;
    而工作队列函数具有更长的延迟并且不需要原子模式;
 3)工作队列函数可以休眠;

2 "工作队列"结构

  注意:2.6.20之后,工作队列的数据结构发生了不少变化,这里列出的接口与数据结构是基于3.2.1的。

    #include<linux/workqueue.h>  
    struct workqueue_struct {/*定义在kernel/workqueue.c*/}; /*工作队列结构*/  
    struct work_struct {       /*向工作队列提交一个任务的任务结构*/  
        atomic_long_t data;  
        struct list_head entry;  
        work_func_t func;     /*work_func_t 定义如下*/  
        /*省略其他成员变量*/  
    }  
    typedef void (*work_func_t)(struct work_struct *work);  


3 "工作队列"接口
 这里只列出一些重要的接口,如果想查看更多接口,可参看"linux/workqueue.h"文件。
 3.1 创建工作队列

    /*这两个是宏,使用时name不用加双引号,这里这样写只是更好地表达该宏的用途*/  
    struct workqueue_struct *create_workqueue(const char *name) /*在系统中的每个处理器上为该工作队列创建专用线程*/  
    struct workqueue_struct *create_singlethread_workqueue(const char *name) /*只创建一个专用线程*/  

3.2 创建工作(work_struct)

    DECLARE_WORK(name,func); /*定义名为name的work_struct类型变量,使用时name不用加双引号,func是work_func_t类型*/  
    INIT_WORK(struct work_struct *work,work_func_t func); /*添充work变量,首次构造该结构时使用*/  
    INIT_DELAYED_WORK(struct work_struct *work,work_func_t func);   
    PREPARE_WORK(struct work_struct *work,work_func_t func); /*如果工作已提交到工作队列时,而只需修改该结构时使用*/  


 3.3 提交工作到工作队列
    int queue_work(struct workqueue_struct *wq, struct work_struct *work);  
    int queue_delayed_work(struct workqueue_struct *wq, struct_work *work,unsigned long delay); /*工作至少会被延迟delay后被执行*/  


3.4 取消工作
    int cancel_delayed_work(struct work_struct *work); /*如果工作在开始执行前被取消,则返回非零值*/  
    void flush_workqueue(struct workqueue_struct *wq); /*该函数返回后,任何在该函数调用之前被提交的工作都不会在系统任何地方运行*/  


3.5 销毁"工作队列"
    void destroy_workqueue(struct workqueue_struct *queue);  

4 共享队列
 如果对工作队列使用不是很频繁的话,则可以使用内核提供的共享的默认队列;需要注意的是,使用该共享队列时不应该长期独占它,而且任务可能需要等待更长的时间后才被执行;一般情况下,推荐使用共享队列。
 共享队列接口
[cpp] view plain copy
  1. int schedule_work(struct work_struct *work); /*提交工作任务到共享队列*/  
  2. int schedule_delayed_work(struct work_struct *work,unsigned long delay);  
  3. void flush_scheduled_work(void);  
5 示例代码
 这里只是演示如何使用“工作队列”,并没有在中断处理中使用。
 5.1 自己创建工作队列
[cpp] view plain copy
  1. #include <linux/module.h>  
  2. #include <linux/init.h>  
  3. #include <linux/workqueue.h>  
  4.   
  5. MODULE_LICENSE("Dual BSD/GPL");  
  6. MODULE_AUTHOR("Kozo");  
  7.   
  8. struct my_struct{  
  9.     char *name;  
  10.     struct work_struct my_work;  
  11. };  
  12.   
  13. static void display(struct work_struct *work)  
  14. {  
  15.     struct my_struct *my_name = container_of(work,struct my_struct, my_work);  
  16.     printk(KERN_DEBUG"name = %s\n",my_name->name);  
  17. }  
  18.   
  19. static struct workqueue_struct *my_wq;  /*注意要全局变量*/  
  20. static struct my_struct my_name;        /*注意要全局变量*/  
  21.   
  22. static int __init demo_init(void)  
  23. {  
  24.     my_wq = create_workqueue("my wq");  
  25.     my_name.name = "Kozo";  
  26.     INIT_WORK(&(my_name.my_work), display);  
  27.     queue_work(my_wq,&(my_name.my_work));   /*转着注:类似于schedule_work,区别在于queue_work把给定工作提交给创建的工作队列wq而不是缺省队列。*/  
  28.     return 0;  
  29. }  
  30.   
  31. static void __exit demo_exit(void)  
  32. {  
  33.     printk(KERN_DEBUG"Goodbye\n");  
  34.     destroy_workqueue(my_wq);  
  35. }  
  36. module_init(demo_init);  
  37. module_exit(demo_exit);  
 5.2 使用共享队列
[cpp] view plain copy
  1. #include <linux/module.h>  
  2. #include <linux/init.h>  
  3. #include <linux/workqueue.h>  
  4.   
  5. MODULE_LICENSE("Dual BSD/GPL");  
  6. MODULE_AUTHOR("Kozo");  
  7.   
  8. struct my_struct{  
  9.     char *name;  
  10.     struct work_struct my_work;  
  11. };  
  12.   
  13. static void display(struct work_struct *work)  
  14. {  
  15.     struct my_struct *my_name = container_of(work,struct my_struct, my_work);  
  16.     printk(KERN_DEBUG"name = %s\n",my_name->name);  
  17. }  
  18.   
  19. static struct my_struct my_name;  
  20.   
  21. static int __init demo_init(void)  
  22. {  
  23.     my_name.name = "Kozo";  
  24.     INIT_WORK(&(my_name.my_work), display);  
  25.     schedule_work(&(my_name.my_work));  
  26.     return 0;  
  27. }  
  28.   
  29. static void __exit demo_exit(void)  
  30. {  
  31.     printk(KERN_DEBUG"Goodbye\n");  
  32.     flush_scheduled_work();  
  33. }  
  34. module_init(demo_init);  
  35. module_exit(demo_exit); 
6 执行结果
工作队列_第1张图片

你可能感兴趣的:(工作队列)