http://blog.youkuaiyun.com/mcgrady_tracy/article/details/42264995
工作队列类似于tasklet,它允许内核代码请求某个函数在将来被执行(不是立即执行)。
工作队列相关API定义在<linux/workqueue.h>中。要使用工作队列有两种方式,一是自己创建一个工作队列;二是使用内核提供的工作队列(共享方式)。
一、我们先来看自己创建工作队列的方式
工作队列使用结构体struct workqueue_struct描述,要创建一个工作队列有两个API,即create_workqueue和create_singlethread_workqueue,原型如下:
- struct workqueue_struct *create_workqueue(const char *name);
- struct workqueue_struct *create_singlethread_workqueue(const char *name);
- struct workqueue_struct *keventd_wq;
- keventd_wq = create_workqueue("events");
要向工作队列中提交一个任务,首先需要填充一个struct work_struct,延时任务使用struct delayed_work,内核提供了相关宏:
- DECLARE_WORK(name, void (*func)(void *));
- INIT_WORK(struct work_struct *work, void (*func)(void *));
延时任务使用INIT_DELAYED_WORK宏初始化。
- INIT_DELAYED_WORK(struct delayed_work, void (*func)(void *));
要将任务提交到工作队列中,内核提供了下面两个API:
- int queue_work(struct workqueue_struct *wq, struct work_struct *work);
- int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay);
如果要取消工作队列中的某个任务,使用cancel_delayed_work,原型如下:
- int cancel_delayed_work(struct work_struct *work);
- void flush_workqueue(struct workqueue_struct *wq);
使用完工作队列之后,可以使用destroy_workqueue销毁工作队列:
- void destroy_workqueue(struct workqueue_struct *wq);
内核在初始化时创建了一个工作队列"events",这个工作队列是共享的,所以我们可以向这个队列提交简单的任务处理。
由于这个工作队列已经被创建好了,所以不再需要我们去创建了,直接往工作队列提交任务就可以了,内核为我们提供了相关API:
- int schedule_work(struct work_struct *work);
- int schedule_delayed_work(struct delayed_work *work, unsigned long delay);
如果要取消提交到共享工作队列中的任务,同样可以使用前面的cancel_delayed_work函数,如果cancel_delayed_work函数返回0,不再使用前面的flush_workqueue函数了,而是使用flush_scheduled_work函数。
- void flush_scheduled_work(void);