文章目录
第五章:CPU调度
在实际应用中,术语线程调度和进程调度常常被交替使用
本章在讨论普通调度概念的时候使用进程调度,特别指定为线程调度概念时使用线程调度
5.1 基本概念
5.1.1 CPU-I/O区间周期
- 进程执行由CPU执行和I/O等待周期组成,进程在这两个状态之间切换
- 进程执行从CPU区间(CPU burst)开始,在这之后是I/O区间(I/O burst),接着是另一个CPU区间,然后是另一个I/O区间,以此类推
下面给出两个图,演示CPU区间和I/O区间的交替以及CPU区间的时间曲线图(频率)
5.1.2 CPU调度程序
每当CPU空闲时,操作系统就必须从就绪队列中选择一个进程来执行。
进程选择由短期调度程序或CPU调度程序执行。调度程序从内存中选择一个能够执行的进程,并为之分配CPU
5.1.3 抢占调度
CPU调度的时机会在以下四种情况下发生
- 当一个进程从运行状态切换到等待状态(主动让出CPU)
- 当一个进程从运行状态切换到就绪状态(如出现中断)
- 当一个进程从等待状态切换到就绪状态(I/O完成)
- 当一个进程终止时
对于第1种情况和第4种情况,调度方案被称为非抢占调度,采用非抢占调度,一旦CPU分配给一个进程,那么该进程会一直使用CPU直到进程终止或进程切换到等待状态
对于第2种和第3种情况,被称为抢占调度
5.1.4 分派调度
与CPU调度功能有关的另一个部分是分派程序,分派程序是一个模板,用来将CPU的控制交给由短期调度程序选择的进程
主要功能:
- 切换上下文
- 切换到用户模式
- 跳转到用户程序的合适位置,以重新启动程序
分派程序应该尽可能快,因为在每次进程切换中都会使用
分派程序停止一个进程而启动另一个新进程所花的时间称为分派延迟
5.2 调度准则
不同的CPU调度算法具有不同的属性,因此为了比较不同的CPU调度算法,提出了很多准则
这里罗列了几个准则:
- CPU使用率:即使CPU尽可能忙。CPU使用率从0%~100%
- 吞吐量:指一个时间单元内所完成的进程的数量。对于长进程,吞吐量可能为每小时一个进程。对于短进程,吞吐量可能为每秒10个进程
- 周转时间:从进程提交到进程完成的时间称为周转时间
- 等待时间:等待时间为进程在就绪队列中等待所花的时间之和(注意这里的等待时间指的是进程处于ready状态,而不是处于waiting状态)
- 响应时间:从提交请求到产生第一响应的时间
CPU调度算法最好使CPU使用率和吞吐量最大化,并使周转时间,等待时间和响应时间最小化
5.3 调度算法
5.3.1 先到先服务调度
- 先到先服务调度是最简单的CPU调度算法
- 先到先服务算法:FCFS(first-come,first-served)
- 先请求的CPU进程先分配到CPU
- FCFS策略可以用FIFO队列实现
图例:
执行顺序为P1,P2,P3
进程P1的等待时间为Oms ,进程P2的等待时间为24ms ,和进程P3的等待时间为27ms 。
平均等待时间为(0 + 24 + 27) / 3 = 17 ms
另一种方式:进程按P2,P3,P1的顺序到达,则其甘特图如下
顺序为P2,P3,P1
平均等待时间为(6 + 0 +3) / 3 = 3 ms,与上面的差别很大
从以上两个例子可以看出,使用FCFS策略的平均等待时间通常不是最小,且如果进程CPU区间时间变化很大,平均等待时间也会变化很大
护航效果:所有其它进程都等待一个大进程释放CPU的情况称为护航效果
比如上面的第一种情况,进程P1耗时比P2,P3进程都长很多,但是P1进程占有了CPU
护航效果会使CPU和设备的使用率变低
FCFS调度算法是非抢占的,一旦CPU被分配给了一个进程,该进程就会保持CPU直到释放CPU为止,即程序终止或请求I/O
5.3.2 最短作业优先调度
最短作业优先调度:SJF(shortest-job-first)
这一算法将每个进程与其下一个CPU区间段相关联。当CPU空闲时,它会赋给具有最短CPU区间的进程。如果两个进程有相同长度,可以使用FCFS调度来处理
非抢占的SJF算法
执行顺序为P4->P1->P3->P2
进程P1的等待时间是 3ms ,进程P2的等待时间为 16ms,进程P3的等待时间为 9ms ,进
程P4的等待时间为 0ms 。因此,平均等待时间为(3 + 16 + 9 +0) / 4 = 7 ms。
抢占的SJF算法:最短剩余时间优先调度(SRTF)
执行顺序为:P1->P2->P4->P1->P3
平均等待时间为((1 0一1) + (1-1) + (1 7-2) +(5-3)) / 4 = 26/4 = 6.5 ms 。
SJF算法的困难之处
SJF算法的困难之处在于如何知道下一个CPU区间的长度
虽然SJF算法最佳,但是它不能在短期CPU调度层次上加以实现,因为没有办法知道下一个CPU区间的长度。
解决方法:用之前CPU区间的长度预测下一个CPU区间的长度
在这个例子里,先猜测CPU区间为10,之后下次猜测的结果 = (前一次猜测的结果 + CPU区间) / 2
比如第二次猜测 8 = (10 + 6)/ 2
5.3.3 优先级调度
- 每个进程都有一个优先级与其关联,具有最高优先级的进程会分配到CPU 。具有相同优先级的进程按FCFS顺序调度
- SJF 算法可作为通用优先级调度算法(priority scheduling algorithm) 的一个特例。
- 优先级区间通常为固定区间的数字,如0-7等。有的操作系统用小数字表示低优先级,有的操作系统用小数字表示高优先级。本书中用小数字表示高优先级
示例
优先级调度可以是抢占的,也可以是非抢占的
优先级算法的问题
优先级调度算法的一个主要问题是无穷阻塞(indefinite blocking) 或饥饿(starvation) 。
无穷阻塞或饥饿的意思是一个进程由于优先级过低,导致很长的时间一直都没执行
解决方法:老化
低优先级进程无穷等待问题的解决之一是老化(aging) 。老化是一种技术,以逐渐增加在系统中等待很长时间的进程的优先级。
比如可以每15分钟提高优先级的值,这样可以让低优先级的进程在经过较长时间后变为高优先级的程序,从而避免出现上面的问题
5.3.4 轮转法调度
- 轮转法(round-robin,RR) 调度算法是专门为分时系统设计的。它类似于FCFS 调度,但是增加了抢占以切换进程。
- 定义一个较小时间单元,称为时间片。时间片通常为10~100 ms。将就绪队列作为循环队列。CPU 调度程序循环就绪队列,为每个进程分配不超过一个时间片的CPU。
例:时间片长度为20 ms
注意点
- 对于RR调度算法,队列中没有进程被分配超过一个时间片的CPU时间(除非它是唯一可运行的进程)。如果进程的CPU区间超过了一个时间片,那么该进程会被抢占,而被放回到就绪队列。
- RR调度算法(轮转法)是可抢占的
- 如果就绪队列中有n个进程且时间片为q,那么每个进程会得到1/ n 的CPU时间,其长度不超过q时间单元。每个进程必须等待的CPU时间不会超过(n-1)*q个时间单元,直到它的下一个时间片为止
- 轮转法在很大程度上依赖于时间片的大小。在极端情况下,如果时间片q非常大,那么轮转法于FCFS算法一样。如果时间片q很小,那么轮转法称为处理器共享
- 选择合适的时间片长度,有利于提高轮转法的效率
5.3.5 多级队列调度
- 在进程可以被分成不同组的情况下,可以建立起另一类调度算法(前台进程和后台进程)
- 多级队列调度算法将就绪队列分成多个独立队列。根据进程的属性,如内存大小,进程优先级,进程类型来确定要分配到哪个队列中
图例:
5.3.6 多级反馈队列调度
- 在多级队列调度中,有一个不太灵活的地方,就是如果一个进程被分配到了某个队列,那么它就一直属于这个队列
- 多级反馈队列调度解决了上面的这个问题,允许进程在队列中移动
- 这种算法的主要思想是根据不同CPU 区间的特点以区分进程。如果进程使用了过多的CPU时间,那么它会被转移到更低的优先级队列
图例
5.4 多处理器调度
这一部分老师上课十分钟左右就讲完了,应该不是重点,主要是几个名词的理解
5.4.1 多处理器调度的方法
- 非对称多处理方法:在多处理器中,CPU 调度的方法是让一个处理器(主服务器)处理所有的调度决定、I/O 处理以及其他系统活动,其他的处理器只执行用户代码。
- 对称多处理方法(每个处理器自我调度):所有进程可能处于一个共同的就绪队列中,或者每个处理器都有它自己的私有就绪进程队列。调度通过每个处理器检查共同就绪队列并选择一个进程来执行。