workqueue实际上就是方便内核中简单的执行某个函数。其本质上在内核创建kthread,由kthread在运行相应的cpu_workqueue_struct中的work。
workqueue中涉及的主要对象有:
Ø work_queue
Ø cpu_workqueue_struct
Ø work_struct/ delayed_work
三者关系如下图所示:
数据结构
(1) work_queue
structworkqueue_struct {
struct cpu_workqueue_struct *cpu_wq;
struct list_head list;
const char *name;
int singlethread;
int freezeable; /* Freeze threads during suspend */
int rt;
};
work_queue中的成员介绍如下:
cpu_wq:work_queue在每个CPU上的队列;
singlethread:如果singlethread为真,则只在一个cpu上创建kthread来运行这个workqueue
rt:是否为real time,如果是rt,则将kthread的调度策略设置为SCHD_FIFO
(2) cpu_workqueue_struct
{
spinlock_t lock;
struct list_head worklist;
wait_queue_head_t more_work;
struct work_struct*current_work;
struct workqueue_struct *wq;
struct task_struct *thread;
}
worklist:该workqueue上挂的work
more_work:该cpu_workqueue_struct上等待的kthread。
wq:指向拥有该cpu_workqueue_struct的work_queue
thread:执行该cpu_workqueue_struct的thread
(3) work_struct/ delayed_work
structwork_struct
{
atomic_long_t data;
struct list_head entry;
work_func_t func;
}
structdelayed_work {
struct work_struct work;
struct timer_list timer;
}
如上所示,work_struct与delayed_work的区别就是delayed_work有一个timer,它将会在指定的时间后,将该work挂入cpu_workqueue_struct。
API
(1) DECLARE_WORK
#define DECLARE_WORK(n, f) \
struct work_struct n =__WORK_INITIALIZER(n, f)
该宏定义了一个名为n的work,其函数执行体为f
(2) DECLARE_DELAYED_WORK
#defineDECLARE_DELAYED_WORK(n, f) \
struct delayed_work n =__DELAYED_WORK_INITIALIZER(n, f)
该宏定义了一个名为n的delay work,其函数执行体为f
(3) 创建work queue
#definecreate_workqueue(name) __create_workqueue((name), 0, 0, 0)
#definecreate_rt_workqueue(name) __create_workqueue((name), 0, 0, 1)
#definecreate_freezeable_workqueue(name) __create_workqueue((name), 1, 1, 0)
#definecreate_singlethread_workqueue(name) __create_workqueue((name), 1, 0, 0)
上面的宏分别创建了各种形式的workqueue
(4) 将work添加到指定的work queue中
externint queue_work(struct workqueue_struct *wq, struct work_struct *work);
externint queue_work_on(int cpu, struct workqueue_struct *wq,
struct work_struct *work);
externint queue_delayed_work(struct workqueue_struct *wq,
struct delayed_work *work,unsigned long delay);
externint queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
struct delayed_work *work,unsigned long delay);
(5) 将work添加到指定的中keventd_wq中
将work添加到keventd_wq上进行执行。
externint schedule_work(struct work_struct *work);
externint schedule_work_on(int cpu, struct work_struct *work);
externint schedule_delayed_work(struct delayed_work *work, unsigned long delay);
externint schedule_delayed_work_on(int cpu, struct delayed_work *work,