当当网网站内容建设的分析,网站开发与应用就业方向,刚做的网站怎么才能搜到我,wordpress jigoshop工作队列#xff08; work queue#xff09;是使用内核线程异步执行函数的通用机制。 工作队列是中断处理程序的一种下半部机制#xff0c;中断处理程序可以把耗时比较长并且可能睡眠的函数交给工作队列执行。 工作队列不完全是中断处理程序的下半部。内核的很多模块需要异步…工作队列 work queue是使用内核线程异步执行函数的通用机制。 工作队列是中断处理程序的一种下半部机制中断处理程序可以把耗时比较长并且可能睡眠的函数交给工作队列执行。 工作队列不完全是中断处理程序的下半部。内核的很多模块需要异步执行函数这些模块可以创建一个内核线程来异步执行函数。但是如果每个模块都创建自己的内核线程会造成内核线程的数量过多内存消耗比较大影响系统性能。所以最好的方法是提供一种通用机制让这些模块把需要异步执行的函数交给工作队列执行共享内核线程节省资源。 所以 Workqueue 的主要设计思想一个是并行多个 work 不要相互阻塞另外一个是节省资源多个 work 尽量共享资源 ( 进程、调度、内存 )不要造成系统过多的资源浪费。 为了实现的设计思想workqueue 的设计实现也更新了很多版本。最新的 workqueue 实现叫做 CMWQ(Concurrency Managed Workqueue)并发可管理工作队列也就是用更加智能的算法来实现“并行和节省”。新版本的 workqueue 创建函数改成 alloc_workqueue()旧版本的函数 create_workqueue() 逐渐会被被废弃。 内核使用工作项保存需要异步执行的函数工作项的数据类型是 work_struct需要异步执行的函数的原型如下所示 struct work_struct { atomic_long_t data; struct list_head entry; work_func_t func; #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif };
typedef void(*work_func_t)(struct work_struct *work)
有一类工作项称为延迟工作项数据类型是 delayed_work。把延迟工作项添加到工作队列中的时候延迟一段时间才会真正地把工作项添加到工作队列中。延迟工作项是工作项和定时器的结合可以避免使用者自己创建定时器。 我们可以使用内核定义的工作队列也可以自己创建专用的工作队列。内核定义了以下工作队列 include/linux/workqueue.h extern struct workqueue_struct *system_wq; extern struct workqueue_struct *system_highpri_wq; extern struct workqueue_struct *system_long_wq; extern struct workqueue_struct *system_unbound_wq; extern struct workqueue_struct *system_freezable_wq; extern struct workqueue_struct *system_power_efficient_wq; extern struct workqueue_struct *system_freezable_power_efficient_wq;
kernel/workqueue.c int __init workqueue_init_early(void) { ...... system_wq alloc_workqueue(events, 0, 0); system_highpri_wq alloc_workqueue(events_highpri, WQ_HIGHPRI, 0); system_long_wq alloc_workqueue(events_long, 0, 0); system_unbound_wq alloc_workqueue(events_unbound, WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE); system_freezable_wq alloc_workqueue(events_freezable, WQ_FREEZABLE, 0); system_power_efficient_wq alloc_workqueue(events_power_efficient, WQ_POWER_EFFICIENT, 0); system_freezable_power_efficient_wq alloc_workqueue(events_freezable_power_efficient, WQ_FREEZABLE | WQ_POWER_EFFICIENT, 0); BUG_ON(!system_wq || !system_highpri_wq || !system_long_wq || !system_unbound_wq || !system_freezable_wq || !system_power_efficient_wq || !system_freezable_power_efficient_wq); return 0; }
system_wq如果工作项的执行时间比较短应该使用这个工作队列。早期的内核版本只提供了这个工作队列 称为全局工作队列 函数 schedule_work()和 schedule_delayed_work()使用这个工作队列。 system_highpri_wq高优先级的工作队列。 system_long_wq如果工作项的执行时间比较长应该使用这个工作队列。 system_unbound_wq这个工作队列使用的内核线程不绑定到某个特定的处理器。 system_freezable_wq这个工作队列可以冻结。 system_power_efficient_wq如果开启了工作队列模块的参数“ wq_power_efficient”那么这个工作队列倾向于省电否则和 system_wq 相同。 system_freezable_power_efficient_wq这个工作队列和 system_power_efficient_wq 的区别是可以冻结。
1定义工作项。 定义一个静态的工作项参数 n 是变量名称参数 f 是工作项的处理函数。 DECLARE_WORK(n, f) 定义一个静态的延迟工作项参数 n 是变量名称参数 f 是工作项的处理函数。 DECLARE_DELAYED_WORK(n, f)
使用 DECLARE_DEFERRABLE_WORK(n, f)也可以定义一个静态的延迟工作项和DECLARE_DELAYED_WORK()的区别是它使用可推迟的定时器 deferrable timer。 可推迟的定时器在系统忙的时候工作正常但是在处理器空闲的时候不会处理可推迟的定时器。当一个不可推迟的定时器唤醒处理器的时候才会处理可推迟的定时器。
在运行时动态初始化工作项方法如下。 1 INIT_WORK(_work, _func)初始化一个工作项参数_work 是工作项的地址参数_func 是需要异步执行的函数。 2 INIT_WORK_ONSTACK(_work, _func)初始化一个工作项工作项是栈里面的局部变量参数_work 是工作项的地址参数_func 是需要异步执行的函数。 3 INIT_DELAYED_WORK(_work, _func)初始化一个延迟工作项参数_work 是延迟工作项的地址参数_func 是需要异步执行的函数。 4 INIT_DELAYED_WORK_ONSTACK(_work, _func)初始化一个延迟工作项延迟工作项是栈里面的局部变量参数_work 是延迟工作项的地址参数_func 是需要异步执行的函数。 5 INIT_DEFERRABLE_WORK(_work, _func)初始化一个延迟工作项和 INIT_DELAYED_WORK()的区别是它使用可推迟的定时器。 6 INIT_DEFERRABLE_WORK_ONSTACK(_work, _func)初始化一个延迟工作项延迟工作项是栈里面的局部变量和 INIT_DELAYED_WORK_ONSTACK()的区别是它使用可推迟的定时器。
2全局工作队列。 在全局工作队列中添加一个工作项。 bool schedule_work(struct work_struct *work); 在全局工作队列中添加一个工作项并且指定执行工作项的处理器。 bool schedule_work_on(int cpu, struct work_struct *work); 在全局工作队列中添加一个延迟工作项参数 delay 是把工作项添加到工作队列中之前等待的时间单位是嘀嗒 tick。 bool schedule_delayed_work(struct delayed_work *dwork, unsigned long delay); 在全局工作队列中添加一个延迟工作项并且指定执行工作项的处理器。 bool schedule_delayed_work_on(int cpu, struct delayed_work *dwork,unsigned long delay); 冲刷全局工作队列确保全局工作队列中的所有工作项执行完。 void flush_scheduled_work(void); 3专用工作队列。 分配工作队列的函数是 alloc_workqueue(fmt, flags, max_active, args...) 1参数 fmt 是工作队列名称的格式。 2参数 flags 是标志位可以是 0也可以是下面这些标志位的组合。 WQ_UNBOUND处理工作项的内核线程不绑定到任何特定的处理器。 WQ_FREEZABLE在系统挂起的时候冻结。 WQ_MEM_RECLAIM在内存回收的时候可能使用这个工作队列。 WQ_HIGHPRI高优先级。 WQ_CPU_INTENSIVE处理器密集型。 WQ_POWER_EFFICIENT省电。 3参数 max_active 是每个处理器可以同时执行的工作项的最大数量 0 表示使用默认值256。 4参数 args 是传给参数 fmt 的参数。
下面的函数用来分配一个有序的工作队列。有序的工作队列在任何时刻按照入队的顺序只执行一个工作项。 alloc_ordered_workqueue(fmt, flags, args...)
#define alloc_ordered_workqueue(fmt, flags, args...) \ alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | \ __WQ_ORDERED_EXPLICIT | (flags), 1, ##args)
兼容旧旧接口 #define create_workqueue(name) \ alloc_workqueue(%s, __WQ_LEGACY | WQ_MEM_RECLAIM, 1, (name)) #define create_freezable_workqueue(name) \ alloc_workqueue(%s, __WQ_LEGACY | WQ_FREEZABLE | WQ_UNBOUND | \ WQ_MEM_RECLAIM, 1, (name)) #define create_singlethread_workqueue(name) \ alloc_ordered_workqueue(%s, __WQ_LEGACY | WQ_MEM_RECLAIM, name)
在指定的工作队列中添加一个工作项。 bool queue_work(struct workqueue_struct *wq, struct work_struct *work); 在指定的工作队列中添加一个工作项并且指定执行工作项的处理器。 bool queue_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work); 在指定的工作队列中添加一个延迟工作项参数 delay 是把工作项添加到工作队列中之前等待的时间单位是嘀嗒 tick。 bool queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay); 在指定的工作队列中添加一个延迟工作项并且指定执行工作项的处理器。 bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq,struct delayed_work *work, unsigned long delay); 冲刷工作队列确保工作队列中的所有工作项执行完。 void flush_workqueue(struct workqueue_struct *wq); 销毁工作队列的函数是 void destroy_workqueue(struct workqueue_struct *wq);
4其他编程接口。 取消一个工作项。 bool cancel_work(struct work_struct *work); 取消一个工作项并且等待取消操作执行完。 bool cancel_work_sync(struct work_struct *work); 取消一个延迟工作项。 bool cancel_delayed_work(struct delayed_work *dwork); 取消一个延迟工作项并且等待取消操作执行完。 bool cancel_delayed_work_sync(struct delayed_work *dwork); 等待一个工作项执行完。 bool flush_work(struct work_struct *work); 等待一个延迟工作项执行完。 bool flush_delayed_work(struct delayed_work *dwork); 判断任务项目是否在进行中 bool work_pending(struct work_struct work );/*返回值为真表示正在运行假表示停止*/