之前总结过 相关 工作队列的知识点
这里补充一下
https://www.modb.pro/db/236436
2.4 时, task-queue这老家伙缺陷还真不少,Genesis他在内核里创建了一个后台进程"keventd",专门用于在进程上下文执行工作任务,同时新增了一个全新的tq_context队列,该进程负责处理tq_context队里上的任务
随着版本不断演进,keventd也越来越强大,作为内核重要的基础设施,没日没夜的为大众服务着。
2002年内核大神Ingo Molnar,重构了taskqueue及keventd代码。正式更名为workqueue,同时将“keventd”后台进程更名为“events”。由此工作队列诞生了。
后来events更改为了现在内核中的kworker
// 什么时候做的改变?
// 现在还有
workqueue出现后,taskqueue、keventd彻底退出历史舞台。
- kworker 和 events 的关系
https://unix.stackexchange.com/questions/436671/difference-between-kworker-n-and-events-n
不管这些数据结构有多少,对于使用者来说,就三个概念
1. 工作者线程处理工作队列
2. 将工作任务插入工作队列,并唤醒工作者线程
三者是如何绑定到一起的?
假设CPU 数目为 NR_CPU
A: 一个 struct list_head workqueues 可以索引所有的 workqueue数据结构
A : 是个静态变量,链表头,用于串接 所有的 "struct workqueue_struct"
A与B:链表上有很多个 alloc_workqueue 创建的 struct workqueue_struct 结构体
B: 一个 struct workqueue_struct 可以索引 一个workqueue成员的所有东西
B与C:有 NR_CPU 个 worker_pool
C : 一个 struct worker_pool , 可以所引挂到该workqueue的所有任务
以下红色框是进程相关
1. 初始化
创建 worker_thread
3. alloc_workqueue
创建 1个 rescuer_thread , 4个(?) worker_thread (该thread由worker_thread创建)
运行时
一但运行起来,会一直在 worker_thread 循环, 在 schedule 睡眠, 在 schedule 唤醒
[<7f024018>] (test_work_func [work_myqueue]) from [<8003d084>] (process_one_work+0x154/0x484)
[<8003d084>] (process_one_work) from [<8003dcbc>] (worker_thread+0x54/0x55c)
[<8003dcbc>] (worker_thread) from [<80042928>] (kthread+0xec/0x104)
[<80042928>] (kthread) from [<8000ec60>] (ret_from_fork+0x14/0x34)
以下绿色框是任务
创建好任务结构体,与 alloc_workqueue 返回的符号绑定,从而落到了 对应核心 的workpool 中的 worklist