Linux 的进程调度是一个分层、可扩展、基于调度类(scheduler class) 的体系,核心思想可以概括为:按调度类优先级选择 → 在选中的调度类里按策略选进程 → 根据时间片或事件触发切换。下面从整体架构 → 调度类与策略 → 调度流程 → 关键机制 → 常见调度器演变系统说明。
Linux 调度器不是“一个算法”,而是 调度类 + 调度策略 的组合:
调度器核心
├── 调度类(sched_class)按优先级排列
│ ├── stop_sched_class (最高,用于 CPU 停止)
│ ├── dl_sched_class (Deadline)
│ ├── rt_sched_class (实时)
│ ├── fair_sched_class (CFS,普通进程)
│ └── idle_sched_class (idle)
└── 每个调度类有自己的一套调度策略
调度时:
| 调度类 | 用途 |
|---|---|
stop |
内核紧急任务(迁移、停 CPU) |
dl |
Deadline 调度(实时) |
rt |
实时进程(RT) |
fair |
普通进程(CFS,最常见) |
idle |
空闲任务 |
SCHED_OTHER / SCHED_NORMAL
SCHED_FIFO
SCHED_RR
SCHED_DEADLINE
让每个进程“看起来”都在公平地使用 CPU
CFS 不维护固定时间片,而是维护 vruntime(虚拟运行时间)。
vruntime += 实际运行时间 × (NICE_0_LOAD / 进程权重)
✅ 总是选择 vruntime 最小的进程运行
vruntime 放入红黑树schedule()
tick 中断 / 事件
↓
schedule()
↓
pick_next_task()
↓
遍历调度类
↓
选定进程
↓
context_switch()
nice -n 10 ./app
renice -n -5 -p PID
chrt -f 10 ./app
| 函数 | 作用 |
|---|---|
sched_setscheduler() |
设置调度策略 |
sched_getparam() |
获取调度参数 |
sched_yield() |
主动让出 CPU |
setpriority() |
设置优先级 |
| 版本 | 调度器 |
|---|---|
| 2.4 | O(n) |
| 2.6 早期 | O(1) |
| 2.6.23+ | CFS(至今) |
CFS 就像一个公平的裁判:
每个人跑得时间不同,但裁判保证“谁跑得少,就让谁先跑”。
Linux 调度 = 调度类优先级 + 调度策略 + vruntime 公平 + 事件驱动抢占
如果你愿意,我可以:
schedule()你更想深入哪一块?