第五十五章:结丹圆满
结丹圆满涉及内核源码:
一
林小源站在调度竞技场的中央,回望来时的路。
从 CFS 的红黑树到 RT 的优先级队列,从 Deadline 的时间契约到 idle 的低功耗等待,从上下文切换的寄存器手术到负载均衡的多核博弈——他走过了调度器的完整路径。
竞技场上空,五位调度类的守关人并肩而立。stop 的身影依然模糊,Deadline 的金色长袍在风中飘动,RT 的银色铠甲反射着光芒,CFS 的绿色长衫温文尔雅,idle 少年靠在柱子上打着哈欠。
"你已经走了很远。"CFS 从空中落下,站在林小源面前。
林小源抱拳行礼:"多谢前辈一路指引。"
CFS 摇摇头:"不是我指引你,是你自己走过来的。调度器的每一个环节——vruntime、红黑树、时间片、唤醒抢占、上下文切换、负载均衡——你都亲眼看过、亲手摸过。现在,你理解了吗?"
林小源沉默了片刻,然后说:"我理解了调度器的机制,但更重要的是,我理解了调度器的哲学。"
二
林小源走到竞技场的边缘,坐在一块石头上。
调度仙子从远处走来,在他身边坐下。她的长裙上绣着调度器的所有数据结构——rq、sched_entity、cfs_rq、sched_class——每一个都在微微发光。
"你学到了什么?"她问。
林小源看着竞技场上的进程们,说:"公平不是平均。CFS 的公平是按权重分配——权重高的进程获得更多 CPU 时间,权重低的进程获得更少。这不是平均主义,而是按需分配。"
调度仙子点头:"继续。"
"选择取决于需求。CFS 适合普通进程,RT 适合实时任务,Deadline 适合硬实时任务。没有'最好'的调度器,只有'最合适'的调度器。每种调度器都有自己的适用场景,它们是互补的,不是替代的。"
"还有呢?"
"权衡是永恒的主题。延迟和吞吐量、缓存亲和性和负载均衡、性能和能效——每一个优化都有代价,每一个选择都有权衡。调度器的目标不是让每个因素都最优,而是让整体效果最好。"
调度仙子微笑着站起身来:"你已经准备好了。"
三
林小源站起身来,感受到了一股力量从丹田涌起。
那是结丹圆满的力量——他对调度器的理解已经达到了一个临界点。从 到 ,从 CFS 红黑树到 RT 调度器,从上下文切换到负载均衡——每一个环节都清晰地呈现在他眼前。
"结丹圆满。"他低声说。
但这只是开始。调度器只是内核的一个子系统。内存管理、文件系统、网络栈、设备驱动——还有无数的领域等待他去探索。
他抬头望向内核的深处。那里有更复杂的机制、更精妙的设计、更深邃的哲理。他还没有遇到内存长老、VFS 阁主、网络真人——那些传说中的存在。
但他已经准备好了。
idle 少年从柱子旁走来,拍了拍他的肩膀:"别忘了我。当你在其他子系统中遇到困难时,回来找我。idle 永远在这里。"
林小源笑了:"谢谢你,idle 前辈。"
他转身走向内核的深处,脚步坚定而从容。身后,调度竞技场渐渐远去,但那些教训——公平、效率、权衡、选择——将永远伴随着他。
天道均衡,亦酬进取。
/*
* 调度器的完整图景:
*
* 核心函数:
* schedule() — 调度入口
* pick_next_task() — 选择下一个进程
* context_switch() — 上下文切换
* scheduler_tick() — 时钟中断处理
* try_to_wake_up() — 唤醒进程
* select_task_rq() — 选择目标 CPU
* load_balance() — 负载均衡
*
* 调度类:
* stop > dl > rt > fair > idle
*
* 数据结构:
* struct rq — per-CPU 运行队列
* struct sched_entity — 调度实体
* struct cfs_rq — CFS 运行队列
* struct sched_class — 调度类
*
* 关键概念:
* vruntime — 虚拟运行时间
* nice / prio — 优先级
* 时间片 — 按权重分配
* 唤醒抢占 — 降低延迟
* 负载均衡 — 多核公平
*/
struct sched_summary {
const char *concept;
const char *key_point;
};
printf("=== 调度器全貌 ===\n\n");
struct sched_summary items[] = {
{ "CFS 调度器", "vruntime + 红黑树,按权重分配 CPU 时间" },
{ "RT 调度器", "FIFO/RR,实时优先级 1-99" },
{ "Deadline 调度器", "runtime/deadline/period,时间保证" },
{ "上下文切换", "保存/恢复寄存器 + 切换页表 + TLB" },
{ "负载均衡", "per-CPU 运行队列 + 调度域层次" },
{ "唤醒抢占", "醒来进程可以抢占当前进程" },
{ "调度类", "多态设计,stop > dl > rt > fair > idle" },
{ "睡眠与唤醒", "TASK_INTERRUPTIBLE / TASK_UNINTERRUPTIBLE" },
{ "idle 进程", "最后选择,HLT/WFI 节能" },
{ "内核抢占", "preempt_count 控制抢占深度" },
};
int nr = sizeof(items) / sizeof(items[0]);
printf("%-16s %s\n", "概念", "关键点");
printf("%-16s %s\n", "---", "---");
for (int i = 0; i < nr; i++) {
printf("%-16s %s\n", items[i].concept, items[i].key_point);
}
printf("\n--- 调度器的设计哲学 ---\n");
printf("公平: CFS 保证每个进程按权重获得 CPU 时间\n");
printf("效率: per-CPU 运行队列 + O(log n) 红黑树\n");
printf("响应: 唤醒抢占 + 内核抢占\n");
printf("可扩展: 调度类多态设计 + 调度域层次\n");#include <stdio.h>
/*
* 调度器的完整图景:
*
* 核心函数:
* schedule() — 调度入口
* pick_next_task() — 选择下一个进程
* context_switch() — 上下文切换
* scheduler_tick() — 时钟中断处理
* try_to_wake_up() — 唤醒进程
* select_task_rq() — 选择目标 CPU
* load_balance() — 负载均衡
*
* 调度类:
* stop > dl > rt > fair > idle
*
* 数据结构:
* struct rq — per-CPU 运行队列
* struct sched_entity — 调度实体
* struct cfs_rq — CFS 运行队列
* struct sched_class — 调度类
*
* 关键概念:
* vruntime — 虚拟运行时间
* nice / prio — 优先级
* 时间片 — 按权重分配
* 唤醒抢占 — 降低延迟
* 负载均衡 — 多核公平
*/
struct sched_summary {
const char *concept;
const char *key_point;
};
int main() {
printf("=== 调度器全貌 ===\n\n");
struct sched_summary items[] = {
{ "CFS 调度器", "vruntime + 红黑树,按权重分配 CPU 时间" },
{ "RT 调度器", "FIFO/RR,实时优先级 1-99" },
{ "Deadline 调度器", "runtime/deadline/period,时间保证" },
{ "上下文切换", "保存/恢复寄存器 + 切换页表 + TLB" },
{ "负载均衡", "per-CPU 运行队列 + 调度域层次" },
{ "唤醒抢占", "醒来进程可以抢占当前进程" },
{ "调度类", "多态设计,stop > dl > rt > fair > idle" },
{ "睡眠与唤醒", "TASK_INTERRUPTIBLE / TASK_UNINTERRUPTIBLE" },
{ "idle 进程", "最后选择,HLT/WFI 节能" },
{ "内核抢占", "preempt_count 控制抢占深度" },
};
int nr = sizeof(items) / sizeof(items[0]);
printf("%-16s %s\n", "概念", "关键点");
printf("%-16s %s\n", "---", "---");
for (int i = 0; i < nr; i++) {
printf("%-16s %s\n", items[i].concept, items[i].key_point);
}
printf("\n--- 调度器的设计哲学 ---\n");
printf("公平: CFS 保证每个进程按权重获得 CPU 时间\n");
printf("效率: per-CPU 运行队列 + O(log n) 红黑树\n");
printf("响应: 唤醒抢占 + 内核抢占\n");
printf("可扩展: 调度类多态设计 + 调度域层次\n");
return 0;
}道藏笔记
内核启示
调度器是 Linux 内核的核心子系统之一。
本卷覆盖的核心概念:
CFS 调度器:
- vruntime + 红黑树
- 按权重分配 CPU 时间
- 唤醒抢占降低延迟
RT 调度器:
- FIFO/RR 两种策略
- 实时优先级 1-99
- 总是优先于 CFS
Deadline 调度器:
- runtime/deadline/period
- 截止时间保证
- 可调度性测试
调度器的基础设施:
- per-CPU 运行队列
- 调度类多态设计
- 上下文切换
- 负载均衡
- 睡眠与唤醒
结丹圆满,方可窥见更深的内核之道。
结丹圆满之试
本卷收束时回到调度器根本问题:每次调度最终要调用哪个函数选出下一任务?