回顾:
- 进程有与之相关联的“控制结构”,即进程控制块和进程表。
- 进程可以有不同的状态,内核触发这些状态之间的转换。
- 操作系统维护多个进程队列。
- 操作系统代表用户管理进程。
本章小结:
- 进程调度简介
- 进程调度程序的类型
- 调度算法的评价标准
- 典型的进程调度算法
进程调度(Process Scheduling)
操作系统负责管理和调度进程:
- 决定何时允许进程进入系统(new→ready)
- 决定接下来运行哪个进程(ready→run)
- 决定何时中断哪些进程((running→ready)
它依赖于调度程序(scheduler / dispatcher)来决定下一个运行哪个进程,它使用调度算法来执行此操作
调度程序使用的算法类型受操作系统类型的影响(例如,实时还是批处理)
进程调度程序(Process Schedulers)
按时间范围分类
长期:适用于新进程,并通过决定何时允许哪些进程进入系统来控制多道程序设计的程度
- CPU和I/O绑定进程的良好组合有利于保持所有资源尽可能繁忙
- 通常在流行的现代操作系统中不存在
中期:控制交换和多编程的程度
短期:决定接下来运行哪个进程
- 管理就绪队列
- 调用非常频繁,因此必须快速
- 通常在响应时钟中断、I/O中断或阻塞系统调用时调用

按方法分类
非抢占式(Non-preemptive):进程只被自愿中断(例如,I/O操作或“nice”系统调用- yield())
- Windows 3.1和DOS是非抢占性的
抢占式(Preemptive):进程可以强制中断,也可以自愿中断
- 通常由来自系统时钟的中断驱动。
- 需要额外的上下文切换,这会产生开销,应该避免过多的上下文切换(回想上一讲)
- 防止进程独占CPU
- 大多数流行的现代操作系统都是抢占式的
性能评估标准
面向用户(User oriented)的标准:
- 响应时间 Response time:尽量减少从创建作业到首次执行作业之间的时间
- 周转时间 Turnaround time:尽量缩短从创造作业到完成作业的时间
- 可预测性:尽量减少处理时间的差异
面向系统(System oriented)的标准:
- 吞吐量:最大限度地提高每小时处理的作业数量
- 公平:处理能力/等待时间是否均匀分配?是否有些进程等待的时间过长(饥饿,starvation)
进程饥饿(starvation)
进程饥饿是操作系统中因资源分配策略不公导致特定进程长期无法获得必需资源的运行状态。其核心特征是等待时间超过可接受阈值,致使进程无法正常推进任务。该现象常发生于短作业优先调度算法、非公平锁机制等场景,与死锁存在本质差异:死锁涉及多个进程的循环阻塞,而饥饿可由单个资源被持久占用引发
评估标准可能是相互冲突的,例如,改进响应时间可能需要更多的上下文切换,从而降低吞吐量并增加周转时间
调度算法
算法考虑:
- 先到先得(FCFS)/先进先出(FIFO)
- 以最短作业优先
- 循环赛
- 优先队列
使用的绩效衡量标准:
- 平均响应时间:所有进程启动所需时间的平均值
- 平均周转时间:所有工序完成所需的平均时间
先到先得(FCFS)
概念:一种非抢占式算法,作为一种严格的排队机制,按照加入队列的顺序对进程进行调度
优点:位置公平,易于实现
缺点:
- 喜欢长过程而不是短过程(想想超市结账!)
- 是否会损害资源利用率,即CPU vs. I/O设备

最短作业优先
概念:一种非抢占式算法,使用已知的预估处理时间,按处理时间升序启动处理(根据任务的长度来确定执行顺序,任务越短,优先级越高)
优点:总能获得最佳的周转时间
缺点:
- 可能会发生饥饿
- 公平性和可预测性受到了损害
- 处理时间必须事先知道

循环赛 (轮询)
概念:FCFS的抢占式版本,强制以周期性间隔或时间片进行上下文切换
- 进程按照添加到队列中的顺序运行
- 进程被计时器强制中断
优点:
- 改进的响应时间
- 有效的一般用途的互动/时间共享系统
时间共享(time sharing)
一种情况,即中央计算机系统允许不同用户同时访问不同程序的情况。
缺点:
- 增加上下文切换,从而增加开销
- 优先使用CPU绑定进程(通常运行时间长)而不是I/O进程(运行时间短);可以通过使用多个队列来防止吗?
- 能减少到FCFS
时间片的长度必须仔细考虑!
例如,假设一个多编程系统具有抢占式调度,上下文切换时间为1ms:
- 一个好的(低)响应时间是用一个小的时间片(例如:1ms)⇒低吞吐量
- 通过大时间片(例如1000ms)实现高吞吐量⇒高响应时间
如果一个时间片只被部分使用,那么下一个进程将立即启动

优先队列
概念:按优先级调度进程的抢占式算法(高→低)
- 在相同的优先级级别内使用轮询
- 进程优先级保存在进程控制块中
优点:可以对I/O绑定作业进行优先级排序
缺点:低优先级进程可能遭受饥饿(当优先级是静态的时候)

给出使用优先级队列时调度进程的顺序,以及它们启动、结束和中断的时间(所有进程在调度时都可用);您可以假设时间片为15毫秒;计算平均响应和周转时间
解决方案:
- 序列: A(15)⇒B(15)⇒A(15)⇒B(15)⇒A(15)⇒B(7)⇒A(15)⇒A(7)⇒C(14)⇒D(15)⇒D(1)
- 平均响应时间= (0 + 15 + 104 + 118) / 4
- 平均周转时间= (82 + 104 + 118 + 134) / 4
注意:我们忽略了上下文切换时间