第 5 章 进程调度
CPU调度是多道程序操作系统的基础。
5.1 CPU调度程序
CPU调度的任务是,从就绪队列中选择一个等待进程,并未其分配CPU。进程选择采用短期调度程序,调度程序从内存中选择一个能够执行的进程并为其分配CPU。
就绪队列不必是FIFO队列,队列内的记录通常为进程控制块PCB。
5.1.1 抢占调度
需要CPU调度的情况可分为以下四种:
- 当一个进程从运行状态切换到等待状态时(例如,I/O请求,或wait()调用以便等待子进程的终止)
- 当一个进程从运行状态切换到就绪状态时(例如出现中断时)
- 当一个进程从等待状态切换到就绪状态时(例如I/O完成)
- 当一个进程终止时
对于第一和第四中情况,除了调度没有选择。一个新进程必须被选择执行。
如果调度只发生在第一和第四种情况下,则调度方案称为非抢占的或协作的;否则,调度方案称为抢占的。在非抢占调度下,一旦某个进程分配到CPU,该进程就会一直使用CPU,直到它终止或切换到等待状态。
5.1.2 调度程序
与CPU调度功能有关的另一个组件是调度程序。调度程序是一个模块,用来将CPU控制交给短期调度程序选择的进程。这个功能包括:
- 切换上下文
- 切换到用户模式
- 跳转到用户程序的合适位置,以便重新启动程序
调度程序应尽可能块,因为在每次进程切换时都要使用。调度程序停止一个进程而启动另一个进程所需要的时间称为调度延迟。
5.2 调度准则
为了比较CPU调度算法,可以采用许多比较准则:
- CPU使用率:应使CPU尽可能忙碌;
- 吞吐量:单位时间内进程完成的数量;
- 周转时间:从进程提交到进程完成的时间称为周转时间,周转时间为所有时间段之和,包括等待进入内存、在就绪队列等待、在CPU上执行和I/O执行;
- 等待时间:在就绪队列中等待所花的时间;
- 响应时间:从提交请求到产生第一个响应的时间,是开始响应所需的时间,而非输出响应所需的时间。
最大化CPU使用率和吞吐量,并最小化周转时间、等待时间和响应时间是可取的。大多数情况下优化的是平均值。
5.3 调度算法
CPU调度处理的问题是:从就绪队列中选择进程以便为其分配CPU。
5.3.1 先到先服务(First-Come First-Served,FCFS)
非抢占的。采用这种方案,先请求CPU的进程首先分配到CPU。FCFS策略可以通过FIFO队列实现。当一个进程进入就绪队列时,它的PCB会被链接到队列尾部。当CPU空闲时,它会分配给位于队列头部的进程,并且这个运行进程从队列中移去。
FCFS的缺点是,平均等待时间往往很长。
所有其他进程都等待一个大进程释放CPU,称为护航效果。与让较短进程先进行相比,这会导致CPU和设备的使用率降低。对分时系统特别麻烦。
5.3.2 最短作业优先调度(Shortest-Job-First,SJF)
这个算法将每个进程与下次CPU执行的长度关联起来。当CPU空闲时,它会被赋给具有最短CPU执行的进程。如果长度相同可以由FCFS来执行。最短下次CPU执行。
可以证明SJF调度算法是最优的。
SJF算法真正的困难是如何知道下次CPU执行的长度。SJF调度经常用于长期调度。一般不能在短期调度上实现,因为没有办法知道下次CPU执行长度。
SJF算法可以是抢占的或非抢占的。新进程的下次CPU执行,与当前运行进程的尚未完成的CPU执行时间小时,抢占SJF调度会抢占当前运行进程,而非抢占SJF算法会允许当前进程完成执行。
抢占SJF调度有时称为最短剩余时间优先(Shortest-remaining-time-first)调度。
5.3.3 优先级调度(priority-scheduling)
SJF是通用优先级调度算法的一个特例。
每个进程都有一个优先级与其关联,而具有最高优先级的进程会分配到CPU。具有相同优先的进程按FCFS顺序调度。这里用低数字表示高优先级。
优先级调度可以是抢占的也可以是非抢占的。如果新到达的进程优先级高于当前运行进程的优先级,那么抢占优先级调度会抢占CPU。
优先级调度算法的一个主要问题是无穷阻塞或饥饿(starvation)。可以让某个低优先级进程无穷等待CPU。解决方案之一是老化(aging),即逐渐增加在系统中等待很长时间的进程的优先级。
5.3.4 轮转调度(Round-Robin,RR)
专门为分时系统设计。类似于FCFS调度,但是增加了抢占以切换进程。将一个较小时间单元定义为时间量或时间片(通常为10-100ms)。就绪队列作为循环队列。CPU调度程序循环整个就绪队列,为每个进程分配不超过一个时间片的CPU。
可能有两种情况发生:进程只需少于时间片的CPU执行,对于这种情况进程本身会自动释放CPU,调度程序接着处理下一个进程。否则定时器中断,进而中断操作系统,然后上下文切换。
不过采用RR策略的平均等待时间通常较长。
RR调度是抢占的。RR算法的性能很大程度取决于时间片的大小。我们希望时间片远大于上下文切换时间,但也不能太大,否则会演变成FCFS调度。
5.3.5 多级队列调度
多级队列调度算法将就绪队列分成很多单独队列,每个队列有自己的调度算法。一个进程永久分到一个队列。此外队列之间应有调度,通常采用固定优先级抢占调度,如前台队列可以比后台队列有优先级。
该算法优点是调度开销低,缺点是不够灵活。
5.3.6 多级反馈队列调度
允许进程在队列之间迁移。根据不同CPU执行的特点来区分进程。如果进程使用过多的CPU时间,那么它会被移到更低的优先级队列。这种方案将I/O密集型和交互进程放在更高优先级队列上。此外,在较低优先级队列中等待过长的进程会被迁移到更高优先级队列。这种形式的老化阻止饥饿发生。
缺点是复杂。
5.4 实时cpu调度
实时操作系统要求在截止期限之前得到结果,在截止期限之后得到的结果是无用的。
软实时系统:不保证会调度关键实时进程,只保证这类进程会优先于非关键进程执行。
硬实时系统:保证实时任务在截止期限内得到服务。
最小化延迟
当一个事件发生时,系统应该尽快地响应和服务它。从事件发生到事件得到服务的时间称为事件延迟。
影响实时系统性能的两类延迟:
- 中断延迟:从CPU收到中断到中断处理程序开始的时间。
- 调度延迟:从停止一个进程到启动另一个进程所需的时间。
实时调度算法
- 单调速率调度:为需要更多CPU的任务分配更高的优先级。
- 最早截止优先调度:根据即将到来的截止期限来分配优先级。截止期限越早,优先级越高。
- 比例分享调度:将处理器时间划分成股份,并为每个进程分配一定数量的份额,从而保证每个进程具有按比例的CPU时间分配。
- POSIX实时调度
突然有一天假期结束,时来运转,人生才是真正开始了。