Linux内核新旧工作队列机制的剖析和比较
摘要:在中断驱动的程序设计中,工作队列是一种强有力的工具。但是在Linux2.6.35及其以前的内核版本中,每创建一个工作队列就创建与CPU数目相同的内核线程,耗费大量的内核资源;工作只能严格串行的处理,效率低。为了适应大规模多处理器硬件平台,提高处理效率,Linux2.6.36内核开发了受控并发工作队列机制。这种新机制由内核根据需要创建或销毁线程,工作可以并发的处理,可望替代之前长期使用的专用线程工具。文章详细介绍和剖析新工作队列机制,并通过实验,对比新旧工作队列机制的资源消耗和工作效率。结果表明,新工作队列机制大大减少内核资源的耗费,提高了处理效率。
关键词: Linux内核; 中断驱动; 工作队列; 受控并发工作队列
当一个中断发生时,并不是相关的各个操作都具有相同的急迫性,把所有的操作都放进中断处理程序本身也不合适。Linux内核将整个中断处理流程简单分为两个部分,第一部分是中断处理程序,称为上半部(Top Half),在运行时禁止可屏蔽中断,用于完成关键性的、紧急的处理;其余部分称为下半部(Bottom Half),在运行时开中断,主要完成与中断处理密切相关的工作,即延后执行工作(Deferring Work)。Linux内核提供三种不同形式的下半部实现机制:软中断(Softirq)、Tasklet和工作队列(Work Queue)。其中软中断和Tasklet运行在中断上下文中,不可阻塞。而工作队列由特殊的内核线程—工作者线程(Worker Thread)来执行,运行在进程上下文,可以阻塞。但是由于旧工作队列机制的缺陷,其应用并不普遍,取而代之的是使用专用线程池,如flush-x:y,bdi-default等。新工作队列机制为内核提供一种通用的线程池机制,以替代这些专用线程池[1]。实际上,只要涉及中断驱动的程序设计,工作队列都是一种强有力的工具,比如在实时控制系统中,可以创建工作队列方便高效地响应和执行由外部事件驱动的任务。文章将重点介绍和分析新工作队列机制。对新旧工作队列机制的介绍分析,选择的内核版本分别是2.6.36和2.6.35。
工作队列的设计思想可以类比于现实中的生产流水线 [2]:流水线相当于工作队列中的worklist链表,加工部件相当于中断发生时所产生的工作序列,工人就是工作者线程。当中断发生时,内核将本次中断延后执行的工作序列,放到worklist工作链表中,唤醒工作者线程执行工作。工作者线程在执行时可能阻塞;当worklist中的工作处理完毕后,工作者线程进入空闲状态。从Linux 2.5.41内核引入工作队列直到2.6.35内核, 其运行机制没有大的改动,主要缺点是,在有N个CPU的计算机中,每当创建一个工作队列时,就创建N条流水线,为每条流水线创建一个工作者线程,内核可以向这N条流水线提交该种类的工作(由响应中断的CPU决定)。因此,如果创建X个工作队列,则需要创建N * X个工作者线程,但是只有当流水线上有工作时,线程才运行,其余流水线上的线程都处于空闲状态。大量的线程需要消耗线程的ID资源和大量内存,同时也会增加调度器的负担。这种情况在拥有大量CPU的超级计算机上显得尤为浪费。另一方面,一条流水线上只有一个工作者线程,因此同一流水线上工作的处理是严格串行的,严重制约处理的效率。
为适应大规模多处理器硬件平台,提高工作队列的处理效率,从2.6.36内核开始对工作队列进行彻底的改造。在新的工作队列机制中,内核始终维持N + 1条“工作流水线”,即全局每CPU工作队列gcwq(Global Percpu Workqueue,详见1.1节)。新机制的流水线是通用的,所有来自同一个CPU的中断所产生的工作序列,都放在这条流水线上。每条流水线上的工作者线程“按需分配”,即当一个工作者线程阻塞时,可以让另一个工作者线程来处理该流水线上剩余的工作。当流水线上需要新的工作者线程时,就创建新线程;而当流水线上线程过多时,就销毁线程。同一条流水线上可以有多个工作同时被指派给多个工作者线程,当然任何时刻一条流水线上只有一个工作者线程在运行。这种新的工作队列机制称为受控并发工作队列(Concurrency Managed Workqueue)[3-5]。
1 受控并发工作队列
1.1 全局每CPU工作队列(gcwq)
如果计算机有N个CPU,则内核创建N + 1个gcwq,其结构如下所示:
struct global_cwq {
spinlock_t lock;
unsigned int cpu;
struct list_head worklist;
int nr_workers;
int nr_idle;
struct list_head idle_list;
struct hlist_head busy_hash[BUSY_WORKER_HASH_SIZE];
struct timer_list idle_timer;
struct timer_list mayday_timer;
...
} ____cacheline_aligned_in_smp;
N个gcwq分别与N个CPU一一绑定,管理相关CPU上的工作者线程和中断产生的工作;第N + 1个gcwq称为unbound_global_cwq,其中的工作者线程未与特定的CPU绑定,详见1.4节WQ_UNBOUND标志说明。虽然gcwq也称作“工作队列”,但是与用户创建的工作队列不同,它是内部管理结构,对用户不可见。gcwq中的cpu字段表示与其关联的CPU编号,worklist双向链表存储由中断提交到该CPU上的工作,lock字段为保护gcwq结构体的自旋锁。每个gcwq都维护管理一个工作者线程池,其中的工作者线程有idle(空闲)和busy(工作)两种状态;idle_list双向链表中管理处于idle状态的工作者线程,nr_idle记录其数量;为了快速检索,使用busy_hash哈希链表管理处于busy状态的工作者线程。这些线程负责处理worklist链表中工作。nr_workers记录工作者线程池中线程的数量。
1.2 新工作队列机制的运行
当中断发生时,内核调用queue_work函数将工作序列提交到gcwq。若相关的线程池中没有线程,则内核创建工作者线程;否则唤醒一个工作者线程(异常情况处理见1.4节WQ_RESCUER属性)。工作者线程调用worker_thread函数,该函数在执行中使用gcwq中的自旋锁进行保护,并完成以下动作:
1)线程从idle状态变为busy状态。
2)对所属的gcwq的线程池进行检查管理。设线程A是当前正在执行的线程,若worklist上有多个待处理的工作,则A检查线程池中是否还有处于idle状态的线程,如果存在,设选中的为线程B;否则A将创建并唤醒一个新线程B,B在创建后进入idle状态。因此在处理工作时,线程池中将保持至少一个处于idle状态的线程待命,以便迅速响应和处理worklist上的后继工作。
3)线程A从gcwq的worklist链表中依次取出未处理的工作进行处理。当处理完worklist中所有的工作后,将再一次对线程池进行检查管理,然后进入idle状态并休眠。
4)一旦线程A阻塞且worklist上还有待处理的工作,则线程B开始运行,它调用worker_thread函数重复以上过程。
如3)所述,当工作者线程处理完全部工作后将对线程池进行一次检查管理。此时如果gcwq中空闲的工作者线程过多,其判断条件是nr_idle > 2且(nr_idle - 2) * 4 >= nr_idle,则gcwq将销毁idle状态持续时间超过5分钟的工作者线程。每个gcwq的线程池最终将维护两个处于idle状态的工作者线程。
期刊库(http://www.zgqkk.com),是一个专门从事期刊推广、投稿辅导的网站。
本站提供如何投稿辅导,寻求投稿辅导合作,快速投稿辅导,投稿辅导格式指导等解决方案:省级投稿辅导/国家级投稿辅导/核心期刊投稿辅导//职称投稿辅导。
【免责声明】本文仅代表作者本人观点,与投稿辅导_期刊发表_中国期刊库专业期刊网站无关。投稿辅导_期刊发表_中国期刊库专业期刊网站站对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。请读者仅作参考,并请自行承担全部责任。
投稿辅导服务咨询与期刊合作加盟
陆老师联系QQ: 913775405(普刊)
蒋老师联系QQ: 867306987(核心)
刘老师联系QQ: 271374912(核心)
联系电话:18015016272
17327192284
投稿辅导投稿邮箱:zgqkk365@126.com
期刊推荐
- 《课程教育研究》 旬刊 国家级
- 《网络空间安全》(信息安全与技术)月刊 国
- 《价值工程》旬刊 国家级 科技统计源期刊
- 《高教论坛》 月刊 省级
- 《法制与社会》旬刊 省级
- 《中国教育学刊》月刊 14版北大核心
- 《语文建设》 旬刊 14版北大核心
- 《中国绿色画报》 月刊 国家级
- 《社科纵横》季刊 社科类优秀期刊
- 《求索》月刊 14版北大核心期刊
- 《财会月刊》旬刊 14版北大核心
- 《艺术品鉴》 月刊 省级
- 《中华建设》月刊 国家级 建设类优秀期刊
- 《教学与管理》旬刊 北大核心
- 《当代经济》 旬刊 省级
- 《新课程研究》旬刊 省级 教育类优秀学术期
- 《文教资料》 旬刊 省级
- 《学术界》 月刊 双核心
- 《吉林教育》旬刊 省级 教育类学术期刊
- 《中国农业资源与区划》 月刊 14版北大核心
- 《继续教育研究》月刊 北大核心期刊
- 《财经界(学术版)》半月刊 国家级
- 《电影评介》半月刊 14版北大核心
- 《公路交通科技》 月刊 北大核心
- 《新闻传播》月刊 省级 新闻类优秀期刊