工作队列
linux2.6引入了工作队列.struct workqueue_struct 实例代表一个工作队列. 内核提供了一组函数可以创建一个工作队列.
#define create_workqueue(name) \
alloc_workqueue("%s", WQ_MEM_RECLAIM, 1, (name))
#define create_freezable_workqueue(name) \
alloc_workqueue("%s", WQ_FREEZABLE | WQ_UNBOUND | WQ_MEM_RECLAIM, \
1, (name))
#define create_singlethread_workqueue(name) \
alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM, name)
三种创建方式, create_workqueue 创建一个工作队列,创建工作队列的同时会在每个CPU上创建一个工作者线程,用于处理后续的工作,有多少个cpu 就会创建多少个线程. 如果只想创建一个工作者线程则可以使用第三种create_singlethread_workqueue. 第二种可以看出与第一种类似,这种创建的工作队列可以被冻结.
工作队列创建完成后队列是空的,没工作可做,就休眠了.下一步要向工作队列中添加工作.
工作work_struct
一个 struct work_struct 结构体代表了一个实际的工作, 工作再被添加到工作队列之前要指定工作的函数,使用#define INIT_WORK(_work, _func) 宏定义初始化一个工作. _work 是工作的地址._func 是工作的函数.
struct work_struct my_work;
/*工作函数*/
void fun_work(struct work_struct *work)
{
//
}
INIT_WORK(&sy8809_work,fun_work);
工作初始化好了,就可以把工作添加进工作队列中,工作队列就会自动执行工作了.
/*把工作添加进队列*/
bool queue_work_on(int cpu, struct workqueue_struct *wq,
struct work_struct *work)
/*默认不指定CPU*/
static inline bool queue_work(struct workqueue_struct *wq,
struct work_struct *work)
{
return queue_work_on(WORK_CPU_UNBOUND, wq, work);
}
/*使用预定义的工作队列*/
static inline bool schedule_work(struct work_struct *work)
{
return queue_work(system_wq, work);
}
常用的是queue_work(),把工作放在指定的工作队列中. schedule_work()函数使用了默认的工作队列 system_wq.
注意: 如果一个工作已经在工作队列中还未执行完成则在此放入则不会再次执行. 还有一点, 一个工作队列中可以放入多个工作,但是一个工作阻塞其他工作也是无法执行.
延时工作:struct delayed_work
延时工作队列可以实现延时一段时间再执行放入到工作队列中的工作. 普通的工作放入工作队列之后如果工作队列空闲则会立即执行.
与 work_struct 类似,struct delayed_work 代表一个延时工作队列.函数INIT_DELAYED_WORK(&delay_work, work_function);初始化一个延时工作. 第二个参数就是掩饰工作的工作函数.
初始化完成后就可以调用schedule_delayed_work(&delay_work, msecs_to_jiffies(time_ms)) 第二个参数是延时事件, 时间单位是系统时钟数. 可以用msecs_to_jiffies把我们常用的ms转化为时钟数.