什么是进程调度?
操作系统从就绪队列 里选一个进程占用 CPU 运行,这个选择规则就是调度算法 。
目标:
- 公平
- 响应快
- 吞吐量大
- 平均等待时间短
- 避免饥饿
7 大经典调度算法
1. FCFS 先来先服务
First Come First Served
- 思想:谁先进入就绪队列,谁先运行,一直运行到结束。
- 方式 :非抢占式
- 优点
- 最简单
- 公平、容易实现
- 缺点
- 护航效应:长进程先到,会让后面所有短进程等待很久
- 平均等待时间很长
- 适用:批处理系统,不适合交互式系统
2. SJF 短作业优先
Shortest Job First
- 思想 :每次选择预计运行时间最短的进程先运行。
- 方式 :非抢占式
- 优点
- 平均等待时间最短(理论最优)
- 缺点
- 长作业可能饥饿(一直来短作业,长作业永远不运行)
- 无法提前知道作业运行时间
- 适用:批处理系统
3. SRTN 最短剩余时间优先
Shortest Remaining Time Next
- 思想 :SJF 的抢占版本 。
新进程到来时,如果它需要的时间 < 当前进程剩余时间,就抢占 CPU。 - 方式 :抢占式
- 优点
- 比 SJF 平均等待时间更短
- 缺点
- 长作业饥饿
- 需要不断记录剩余时间,开销稍大
- 适用:需要快速响应短任务的场景
4. 优先级调度 Priority Scheduling
- 思想 :每个进程有优先级,高优先级先运行。
- 方式:可抢占 / 可不抢占
- 优点
- 灵活:重要任务(内核、IO、实时任务)可设高优先级
- 缺点
- 低优先级进程饥饿
- 解决饥饿 :老化(Aging)
进程等待时间越长,优先级自动慢慢升高。 - 适用:通用系统、实时系统
5. RR 时间片轮转
Round Robin
交互式系统(手机/PC)最常用!
- 思想
- 就绪队列按 FCFS 排队
- 每个进程只运行一个时间片(如 10ms~100ms)
- 时间片到,切换下一个,自己排到队尾
- 方式 :抢占式
- 优点
- 响应快
- 公平
- 适合分时/交互式系统
- 缺点
- 时间片太大 → 退化成 FCFS
- 时间片太小 → 进程切换频繁,CPU 开销巨大
- 适用:Linux、Windows、Android、iOS 等
6. HRRN 高响应比优先
Highest Response Ratio Next
兼顾 FCFS 和 SJF,不会饥饿!
-
思想 :每次选响应比最高的进程。
-
响应比公式
响应比 = (等待时间 + 服务时间) / 服务时间 = 1 + 等待时间 / 服务时间- 作业越短 → 响应比越高
- 等待越久 → 响应比越高
-
方式 :非抢占式
-
优点
- 不会饥饿
- 兼顾长短作业
-
缺点
- 每次调度都要计算,开销大
- 难以做成抢占式
-
适用:批处理综合调度
7. 多级反馈队列
Multilevel Feedback Queue
现代操作系统经典综合算法!
-
结构
多个队列,从上到下优先级越来越低 。
每个队列时间片越来越长。
-
规则
- 新进程进入最高优先级队列
- 先调度高优先级队列,同一队列用 RR
- 进程用完时间片还没结束 → 降级到下一级队列
- IO 密集型(短任务)会经常释放CPU → 保持高优先级
- CPU 密集型 → 慢慢降级到低优先级、大时间片
-
优点
- 自动偏向短作业、IO 密集型
- 不需要预先知道运行时间
- 兼顾响应速度与吞吐量
-
缺点
- 算法复杂
-
适用:Unix、Linux 早期、Windows 等通用操作系统
7 种算法总结表
| 算法 | 抢占? | 核心思想 | 优点 | 缺点 | 适用 |
|---|---|---|---|---|---|
| FCFS | 非抢占 | 先来先运行 | 最简单 | 长作业阻塞短作业 | 批处理 |
| SJF | 非抢占 | 选最短 | 平均等待最短 | 长作业饥饿 | 批处理 |
| SRTN | 抢占 | 剩余最短优先 | 更优 | 饥饿、开销大 | 短任务多 |
| 优先级 | 可/否 | 优先级高先跑 | 灵活 | 饥饿(可用老化解决) | 通用/实时 |
| RR | 抢占 | 时间片轮转 | 响应快、公平 | 时间片难选 | 交互式系统 |
| HRRN | 非抢占 | 响应比最高 | 不饥饿、兼顾长短 | 计算开销 | 批处理综合 |
| 多级反馈队列 | 抢占 | 多队列+自动降级 | 综合最优、自适应 | 复杂 | 现代OS |