一、前言
处理器调度 是操作系统内核的核心功能 ,其本质是按一定规则分配 CPU 时间片,让多个进程 / 线程(内核统一视为task)高效、公平地共享 CPU 资源,实现宏观上的并发执行。
调度目标:提高 CPU 利用率、缩短任务响应时间、保证系统公平性、避免进程饥饿。
根据调度的层次和时机 ,处理器调度分为三级调度 ;根据调度对象的状态 ,又分为进程调度和线程调度,下面分模块详解。
二、 三级调度(按调度层次划分)
操作系统的调度分为三个层次,分别对应任务从 "进入系统" 到 "执行完毕" 的不同阶段。
2.1. 作业调度(高级调度)
- 调度对象:作业(用户提交的完整任务,如一个程序的运行请求)。
- 核心作用:从外存的作业后备队列中选择符合条件的作业,调入内存并创建对应的进程,使其参与 CPU 竞争。
- 触发时机:系统空闲时、有新作业提交时(调度频率低,分钟 / 小时级)。
- 适用场景:批处理系统(如大型机的任务调度),分时 / 实时系统一般不设计作业调度。
- 调度算法:先来先服务(FCFS)、短作业优先(SJF)、优先级调度。
2.2. 内存调度(中级调度)
-
调度对象:内存中的进程。
-
核心作用:解决内存资源不足的问题 ------ 将暂时不运行的进程(如阻塞态进程)换出到外存(挂起队列),待需要时再换入内存,重新加入就绪队列。
-
触发时机:内存空间紧张时(调度频率中等,秒级)。
-
核心目标:提高内存利用率和系统吞吐量。
-
关键概念:
挂起态 :进程数据被换出到外存,不参与 CPU 调度,分为阻塞挂起(原阻塞态)和就绪挂起(原就绪态)。
换入 / 换出:外存与内存之间的进程数据迁移。
2.3. 进程 / 线程调度(低级调度)
- 调度对象:内存中的进程 / 线程(内核task)。
- 核心作用:从就绪队列中选择一个任务,分配 CPU 时间片,使其从就绪态转为运行态。
- 触发时机:任务完成、时间片耗尽、任务阻塞、有高优先级任务进入就绪队列(调度频率高,毫秒级)。
- 调度算法:操作系统的核心算法,直接决定系统性能,下文重点讲解。
三、 核心:进程 / 线程调度算法
调度算法是处理器调度的灵魂,不同算法适用于不同的系统场景(批处理、分时、实时)。
| 调度算法 | 核心思想 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 先来先服务(FCFS) | 按任务到达就绪队列的顺序调度,先到先执行 | 公平、实现简单 | 短任务可能被长任务阻塞(convoy effect 护航效应) | 批处理系统、作业调度 |
| 短作业优先(SJF) | 优先选择估计执行时间最短的任务 | 平均等待时间最短 | 长任务可能饥饿、需要预估执行时间 | 批处理系统、作业调度 |
| 最短剩余时间优先(SRTF) | SJF 的抢占式版本:新任务执行时间更短时,抢占 CPU | 比 SJF 更优,平均等待时间更短 | 抢占开销大、需要预估时间 | 批处理系统 |
| 时间片轮转(RR) | 就绪队列任务轮流占用 CPU,每个任务分配固定时间片(如 10ms),时间片到则切换 | 响应时间短、公平,适合交互 | 时间片过短→切换开销大;过长→退化为 FCFS | 分时系统(如 Linux 桌面、Windows) |
| 优先级调度 | 按任务优先级高低调度,优先级高的先执行 | 支持紧急任务优先处理 | 低优先级任务可能饥饿 | 实时系统、进程调度 |
| 多级反馈队列(MLFQ) | 多个就绪队列,不同队列时间片不同;任务按表现动态调整队列(优先级) | 兼顾公平和高效,平衡短任务和长任务 | 实现复杂 | 通用操作系统(如 Linux、Windows) |
| 最高响应比优先(HRRN) | 优先选择响应比 (等待时间+预估执行时间)/预估执行时间) 最大的任务,响应比随等待时间动态提升 |
避免长任务饥饿,平衡短任务响应速度与长任务公平性 | 依赖执行时间预估,每次调度需计算响应比,有额外开销 | 批处理系统(希望避免饥饿的场景) |
关键补充:抢占式 vs 非抢占式调度
-
非抢占式:任务一旦获得 CPU,会一直执行到完成或主动阻塞(如 I/O 等待),才释放 CPU。
典型算法:FCFS、非抢占式 SJF。
优点:切换开销小;缺点:紧急任务无法及时响应。
-
抢占式:操作系统可以强制剥夺正在运行任务的 CPU,分配给更紧急的任务。
典型算法:RR、SRTF、优先级调度。
优点:响应快、支持实时任务;缺点:切换开销大。
四、 线程调度 vs 进程调度
在支持线程的操作系统中(如 Linux),调度的最小单位是线程,而非进程,两者的核心区别如下:
| 维度 | 进程调度 | 线程调度 |
|---|---|---|
| 调度单位 | 进程(独立mm_struct,资源隔离) | 线程(共享进程mm_struct,资源共享) |
| 切换开销 | 大(需切换页表、地址空间等) | 小(仅切换寄存器、程序计数器、栈指针) |
| 资源分配 | 进程是资源分配的最小单位 | 线程是 CPU 调度的最小单位 |
| 核心目标 | 资源隔离与分配 | 高效利用 CPU,实现并发 |
五、 调度的性能评价指标
衡量调度算法好坏的核心指标:
- CPU 利用率:CPU 处于忙状态的时间占比,越高越好(理想 100%)。
- 吞吐量:单位时间内完成的任务数,越高越好。
- 周转时间:任务从提交到完成的总时间,越短越好。
- 平均周转时间 = 总周转时间 / 任务数。
- 等待时间:任务在就绪队列的等待时间总和,越短越好。
- 响应时间:任务从提交到首次获得 CPU 的时间,越短越好(交互系统关键指标)。