需要解决的问题:当多个进程同时竞争CPU时,如何分配下一个要运行的进程。
为了完成这个问题的思考,我们从以下四个方面考虑

进程行为

计算密集型(CPU密集型):具有较长的CPU集中使用和较小频度的I/O等待。
I/O密集型:具有较短的CPU集中使用和频繁的I/O等待。
目前而言,随着CPU性能的飞速提高,更多的进程倾向于I/O密集型。不是因为运算量变小了,而是CPU效率提升的太快了。

何时调度

1、在创建进程时,需要决定运行父进程还是子进程。
2、在一个进程退出时必须做出调度决策。
3、当一个进程阻塞在I/O的信号量或者因为其他原因阻塞时,必须选择另一个进程运行。
4、在一个I/O中断发生时,必须做出调度策略。

调度算法分类

非抢占式:运行到阻塞再被挂起。
抢占式:运行某个固定时段,若还在运行,就会被挂起。

调度算法需要在不同环境下有不同的优化:
1、批处理。批处理系统中,不会有用户不耐烦地在中断等待一个短请求的相应,所以非抢占式或者长时间周期的抢占式算法可能都是可行的。
2、交互式。为了避免一个进程霸占CPU拒绝为其他进程服务,抢占是必须的。
3、实时。抢占有时是不需要的,因为进程了解它们可能会长时间得不到运行,所以通常很快地完成各自的工作并阻塞。

调度算法目标

操作系统 进程调度
一张图解释一切。
之后就分类将不同系统中的调度算法,实时系统我就忽略掉了。

批处理系统中的调度

根据上面分析的那样,批处理系统适合两种非抢占式的调度算法。

先来先服务

非常简单,只需要维护一个单链表就好,每次有新进程变为就绪态时,就加入链表尾部。
但是问题也非常明显,假如有一个计算密集型进程和一个I/O密集型进程,这样的话一定会浪费大量的时间在等待I/O上。

最短作业优先

如果运行时间可以预知的话,可以使用最短作业优先的调度。
但是要注意一个坑,如果有四个进程分别为a,b,c,d分别对应的运行时间为6,5,3,3。并且是以abcd的顺序如就绪队列的,那么第一个获得CPU的进程仍然为a。
当然,也很容易能推理出一个抢占式版本。

最短剩余时间优先

调度总是选择剩余时间最短的进程,每当新进程到达的时候,会对整个就绪队列的最短时间同占用CPU的进程剩余时间进行比较。若新进程更短,则将当前占用CPU进程挂起。

交互式系统中的调度

以下的调度算法在个人机上都是非常常用的。

轮转调度

时间片轮转,很好理解。就绪队列中的每个进程依次运行规定的时间片长度,之后交出CPU。
问题的重点在于时间片的选择长度问题,因为进行进程切换(上下文切换)是需要时间代价的,这时就需要一个合适的时间片长度,使得使用在切换上的时间比重很低,又不至于让时间片过于长而影响用户的使用。

优先级调度

上述时间片轮转调度其实隐含了所有进程同等重要这一个前提条件。但是在优先级调度里面就需要考虑进程的优先级并不一样的情况了。
优先级调度允许优先级最高的进程先运行。但是为了防止高优先级的进程一直无休止地占用CPU,可以在每一个时钟中断时降低当前进程的优先级,如果当前进程的优先级低于次高的优先级,则会发生进程切换。
这也体现出了优先级可以动态赋予的思想。

多级队列

操作系统 进程调度
CTSS的设计者意识到,为CPU密集型进程设置较长时间片比频繁分配给它们短时间片要更高效。但是长时间片又会影响到响应时间,自然分级的思想就出现了。
以图中S1、S2、S3举例说明,S1的时间片为1,S2可能为2,S3可能为4.当一个进程使用完分配的时间片后,会被移入下一类。

最短进程优先

思想很简单,就是找到当前最短进程。但是寻找的方式就称为了问题。
一种方法是根据过去的行为进行推测,并且执行估计运行时间最短的那个。假设某终端上每条命令的估计运行时间为T0,现在假设测量到其下一次运行时间为T1,可以利用两个值的加权来改进估计时间,即αT0+(1-α)T1。通过选择α的值可以决定尽快忘掉老的运行时间。这种通过当前测量值和先前估计值进行加权平均而得到下一个估计值的技术称作老化

保证调度

为了实现所做的保证,系统必须跟踪各个进程自创建以来使用的CPU的时间。然后计算各个进程应该获得多少CPU时间,即自创建以来的时间处以进程数n。由于各个进程使用CPU的时间是已知的,就能计算出真正获得CPU的时间和应当获得CPU的时间的比值。然后算法转向比率最低的进程,直到该进程的比率超过它的最近竞争者。

**调度

基本思想在于,提供各种系统资源(如CPU)的时间片。一旦需要作出一项调度决策的时候,就随机抽出一张**,拥有该**的进程获得该资源。

公平分享调度

在之前的讨论中,讨论的对象都是进程本身,那考虑一种情况,假设用户A有9个进程,用户B有1个进程。那么这样子分配可能就是种不公平。但是这里公平的定义需要在实际情况再讨论。

相关文章: