进程调度
调度解决“CPU 给谁”:目标是在吞吐、延迟、公平之间权衡。面试主线:调度目标、算法演进、Linux 实际用什么。
调度目标
| 目标 | 含义 | 冲突 |
|---|---|---|
| 吞吐量 | 单位时间完成的任务数 | 与延迟此消彼长 |
| 响应时间 | 交互任务从就绪到运行 | 要抢占 |
| 公平性 | 每个进程分到合理 CPU | 与优先级冲突 |
| CPU 利用率 | 别闲着 | 切换别太频繁 |
没有完美的调度器,只有权衡。面试答“看场景选目标”是加分项。
经典算法
| 算法 | 机制 | 特点 |
|---|---|---|
| FCFS(先来先服务) | 排队执行 | 简单,短任务被长任务阻塞(convoy 效应),平均等待长 |
| SJF(最短作业优先) | 最短的先执行 | 平均等待最优,但需要预知运行时间,长任务可能饿死 |
| 时间片轮转(RR) | 每个进程一个时间片轮流 | 公平、响应好,时间片大小是权衡 |
| 优先级调度 | 高优先级先跑 | 低优先级可能饿死(配合老化 aging) |
| 多级反馈队列 | 多队列 + 优先级 + 时间片递增 | 综合方案,兼顾交互和后台 |
多级反馈队列是经典综合答案:新进程进最高优先级队列(短时间片),用完降级(时间片变长),交互任务(频繁让出 CPU)留在高优先级。没被饿死的唯一保障是老化(等待越久优先级越高)。
Linux CFS
Linux 用 CFS(完全公平调度):
- 不再按优先级给时间片,而是维护每个进程的 vruntime(虚拟运行时间,含权重折算)
- 每次选 vruntime 最小的进程运行(红黑树维护)
- 权重(nice 值)影响 vruntime 增长速度:nice 低跑得快、vruntime 长得慢,分到更多 CPU
vruntime 增长速率 = 实际运行时间 / 权重
调度选择 = vruntime 最小的进程- 交互进程(睡眠多)vruntime 小,自动优先:CFS 用 vruntime 天然实现交互优先,不需要显式老化
- 实时进程(RT)走独立调度类(SCHED_FIFO/SCHED_RR),优先级高于普通进程
面试追问
- 调度目标有哪些? 吞吐、响应、公平、利用率。互相冲突,按场景权衡
- 多级反馈队列为什么好? 交互任务优先(高优先级短时间片),后台任务不饿死(降级但仍在跑),配合老化
- CFS 怎么实现公平? 选 vruntime 最小的进程。权重决定增长速度,睡眠多的自动优先
- 时间片大小怎么定? 太短切换开销大,太长响应差。典型 10-100ms 量级
- 优先级和公平怎么平衡? 优先级(权重)影响份额但不饿死:低优先级也在跑,只是慢