作者简介:大家好,我是码炫码哥,前中兴通讯、美团架构师,现任某互联网公司CTO,兼职码炫课堂主讲源码系列专题
代表作:《jdk源码&多线程&高并发》,《深入tomcat源码解析》,《深入netty源码解析》,《深入dubbo源码解析》,《深入springboot源码解析》,《深入spring源码解析》,《深入redis源码解析》等
联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬。码炫课堂的个人空间-码炫码哥个人主页-面试,源码等
释放21集全网最深ConcurrentHashMap的vip视频,复现每一行源码
1. 概述
Workqueue工作队列是利用内核线程来异步执行工作任务的通用机制;Workqueue工作队列可以用作中断处理的Bottom-half机制,利用进程上下文来执行中断处理中耗时的任务,因此它允许睡眠,而Softirq和Tasklet在处理任务时不能睡眠;
来一张概述图:

- 在中断处理过程中,或者其他子系统中,调用
workqueue的调度或入队接口后,通过建立好的链接关系图逐级找到合适的worker,最终完成工作任务的执行;
2. 数据结构
2.1 总览
此处应有图:

-
先看看关键的数据结构:
work_struct:工作队列调度的最小单位,work item;workqueue_struct:工作队列,work item都挂入到工作队列中;worker:work item的处理者,每个worker对应一个内核线程;worker_pool:worker池(内核线程池),是一个共享资源池,提供不同的worker来对work item进行处理;pool_workqueue:充当桥梁纽带的作用,用于连接workqueue和worker_pool,建立链接关系;
下边看看细节吧:
2.2 work
struct work_struct用来描述work,初始化一个work并添加到工作队列后,将会将其传递到合适的内核线程来进行处理,它是用于调度的最小单位。
关键字段描述如下:
struct work_struct {
atomic_long_t data; //低比特存放状态位,高比特存放worker_pool的ID或者pool_workqueue的指针
struct list_head entry; //用于添加到其他队列上
work_func_t func; //工作任务的处理函数,在内核线程中回调
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};
图片说明下data字段:

2.3 workqueue
-
内核中工作队列分为两种:
- bound:绑定处理器的工作队列,每个
worker创建的内核线程绑定到特定的CPU上运行; - unbound:不绑定处理器的工作队列,创建的时候需要指定
WQ_UNBOUND标志,内核线程可以在处理器间迁移;
- bound:绑定处理器的工作队列,每个
-
内核默认创建了一些工作队列(用户也可以创建):
system_mq:如果work item执行时间较短,使用本队列,调用schedule[_delayed]_work[_on]()接口就是添加到本队列中;system_highpri_mq:高优先级工作队列,以nice值-20来运行;system_long_wq:如果work item执行时间较长,使用本队列;system_unbound_wq:该工作队列的内核线程不绑定到特定的处理器上;system_freezable_wq:该工作队列用于在Suspend时可冻结的work item;system_power_efficient_wq:该工作队列用于节能目的而选择牺牲性能的work item;system_freezable_power_efficient_wq:该工作队列用于节能或Suspend时可冻结目的的work item;
struct workqueue_struct关键字段介绍如下:

最低0.47元/天 解锁文章
628

被折叠的 条评论
为什么被折叠?



