调度时机

低级调度从就绪队列中选择一个进程,为它分配 CPU。

900

需要进行进程调度与切换的情况,可以分成两类。

类型 触发情况 含义
当前进程主动放弃 CPU 正常终止 进程执行结束,不再需要 CPU
当前进程主动放弃 CPU 异常终止 运行中发生错误,被迫结束
当前进程主动放弃 CPU 主动阻塞 请求 I/O、等待资源或事件,暂时无法继续运行
当前进程被动放弃 CPU 时间片用完 分时系统用时钟中断周期性收回 CPU
当前进程被动放弃 CPU 有更紧急事件需要处理 例如 I/O 中断到达
当前进程被动放弃 CPU 更高优先级进程进入就绪队列 抢占式调度下,当前进程可能被暂停

主动放弃 CPU 时,当前进程自己已经无法或不需要继续运行。被动放弃 CPU 时,当前进程本来还可以继续执行,但系统为了响应性、公平性或优先级,强行收回 CPU。

不能调度和不能抢占的情况

有些位置即使出现了调度条件,也不能立刻切换进程。

情况 为什么不能立刻切换
正在处理中断 中断处理过程与硬件状态密切相关,通常要先完成中断处理,再到安全点决定是否调度
正在操作系统内核程序临界区 内核可能正在访问就绪队列、PCB 队列等关键数据结构,切换会破坏内核管理数据的一致性
正在执行原语 原语必须原子完成,不能在中途被打断
内核临界区和普通临界区不同

进程处于普通临界区时,不一定禁止处理机调度。比如进程正在使用打印机,打印机是慢速设备,如果一直不允许调度,CPU 可能长期空闲。

不能调度的是操作系统内核程序临界区。这类临界区访问的是内核管理数据,例如就绪队列、阻塞队列、PCB 链表。若这些结构还没维护完就切换,会让后续调度、唤醒、阻塞等操作读到不一致状态。

**中断处理程序可以发现需要调度,但完整的进程切换通常要等到中断处理结束后的安全位置再执行**。

调度方式

进程调度方式按是否允许强行收回 CPU,可分为非抢占式和抢占式。

调度方式 也称 规则 优点 缺点 适用场景
非抢占式调度 非剥夺调度 只允许进程主动放弃 CPU 实现简单,系统开销小 不能及时处理紧急任务 早期批处理系统
抢占式调度 剥夺调度 更重要或更紧急的进程到达时,可以暂停当前进程 响应快,可实现时间片轮转和实时响应 切换开销更大,需要更复杂的保护机制 分时系统、实时系统

非抢占式系统中,运行进程阻塞或退出时才触发调度。抢占式系统中,每个时钟中断或若干个时钟中断都可能触发调度程序工作。

分派器

调度器和分派器不是同一件事。

900

调度器 scheduler 负责做选择:

  • 让谁运行。
  • 按什么调度算法选择。
  • 在时间片轮转等策略中,运行多长时间。

分派器 dispatcher 负责把 CPU 真正交给被选中的进程:

  • 保存当前进程的处理机现场。
  • 恢复新进程的处理机现场。
  • 切换到新进程的地址空间和内核栈等运行环境。
  • 让 CPU 从新进程上次停下的位置继续执行。

可以这样区分:

  • 狭义的进程调度:只指从就绪队列中选中一个进程。
  • 进程切换:一个进程让出 CPU,由另一个进程占用 CPU。
  • 广义的进程调度:选择进程 + 进程切换。

进程切换过程

进程切换主要完成两类动作:

  1. 保存原来运行进程的各种数据。
  2. 恢复新进程的各种数据。

这些数据包括程序计数器 PC、程序状态字 PSW、通用寄存器、栈指针等处理机现场信息。它们通常保存在 PCB 中。

一次典型切换可以按以下顺序理解:

  1. 当前进程因为时间片用完、阻塞、终止或被抢占而离开运行态。
  2. 内核保存当前进程的 CPU 现场到该进程 PCB。
  3. 内核修改当前进程状态,并把 PCB 放入合适队列。
  4. 调度器从就绪队列选择下一个进程。
  5. 分派器从新进程 PCB 恢复 CPU 现场。
  6. 新进程进入运行态,从保存的 PC 位置继续执行。

进程切换有代价。调度和切换过于频繁时,系统会把大量时间花在保存、恢复现场和维护队列上,真正用于执行用户进程的时间反而减少。

闲逛进程

当没有其他就绪进程时,调度程序会选择闲逛进程,即 idle process。

闲逛进程的特点:

  • 优先级最低。
  • 只有没有其他就绪进程时才运行。
  • 可以设计为能耗较低的循环或特殊指令序列。
  • 它占用 CPU 的目的不是完成用户任务,而是让 CPU 在无事可做时保持一个可控状态,并在指令周期末尾继续检查中断。

闲逛进程的存在说明:CPU 在操作系统管理下通常总运行着一个进程。没有用户进程可运行时,就是 idle。