进程调度
当计算机是多道程序时,它时常有多个进程同时竞争CPU,每当两个或较多的进程同时处于准备态时,发生这二种情形,如果只有一个CPU,必须选择接下来运行的进程。
操作系统中做出选择的这一部分称为调度程序(scheduler),其算法称为调度算法(scheduler algorithm)。
调度简介
进程行为

CPU脉冲的利用率随着I/O等待周期交替
- (a) 计算(CPU)密集型的进程
- (b) I/O密集型的进程
上图中需要注意的重要事项就是,某些进程,例如图(a)中那一个,大部分时间都用于计算,而其他的,例如图(b)中的,大部分时间花在等待I/O上。
前者被称为计算密集型(compute-bound);后者叫做I/O密集型(I/O bound),计算密集型的进程通常有长的CPU脉冲,因而很少I/O等待,而I/O密集型的进程有短的CPU突发,因而时常I/O等待。
何时调度
- 新的进程创建时,需要决定时运行父进程还是运行子进程。
- 进程退出的时候,也必须做出调度决策。
- 当一个进程在I/O上、在信号量上或者因为某些其他原因而阻塞时,也必须被选择运行另一个进程。
- 当进程发生I/O中断时,可能要做出调度决策。
- 时钟中断发生时,可能要作出调度决策。
非抢占调度算法和抢占式调度算法
- 非抢占(non-preemptive,非剥夺)调度算法选择一个进程运行,然后一直让它运行知道它阻塞(在I/O上或者等待另一个进程)或者它自动地释放CPU,即使它运行长达数小时,他都不会被强迫种植。
- 抢占式(preemptive,可剥夺)调度算法选择一个进程,而且最多让它运行某个固定的时间。如果它在时间间隔结束时仍正运行,它将被挂起,而且调度程序选择另一个进程来运行(如果有的话)。
调度算法的种类
不同的系统需要不同的算法,分一下三种系统来讨论:
- 批处理
- 交互式
- 实时
调度算法的目标
-
对于所有的系统
- 公平:给每个进程公平的CPU份额;
- 强制策略:确保规定的策略已经实行
- 平衡:保持系统的所有部分不空闲
-
对于批处理系统
-
吞吐量:使每小时的作业数量最大化
吞吐量(Throughout)是指每小时系统完成的作业数量
-
周转时间:使作业提交和结束之间的时间减到最小
周转时间(Turnaround time)是指一个批处理的作业从递交到完成的平均时间
-
CPU利用率:使用保证CPU忙碌
-
-
对于交互式系统
-
响应时间:快速地相应请求
响应时间(response time)即发出一个指令到得到结果之间的时间
-
均衡性:满足用户的期望
-
-
对于实时系统
- 满足时间期限:避免丢失数据
- 可预测性:在多媒体系统中避免降低质量
批处理系统中的调度
先来先服务(First-Come, First-Served/FCFS)
非抢占算法
方法:系统维护一个就绪进程队列。当第一个作业进入系统时,它立刻被启动而且允许它随意运行多久。新作业到来时,被放置在就绪队列尾部。当运行的进程阻塞时,接下来运行队列中的第一个进程。当被阻塞的进程转入就绪态时,就像新到达作业一样,被放在队列的尾部。
该算法的优势就是容易理解,易于编程,而且比较公平。
最短作业优先(Shortest Job First,SJF)
非抢占算法,预知运行时间
方法:系统维护一个有序(作业运行时间升序)就绪进程队列,新作业到达时,插入队列,保持有序。
例如:有4个作业A、B、C和D,运行时间分别为8、4、4和4分钟,它们几乎同时到达系统(按次序A、B、C、D)。

- (a) 按先来先服务次序运行4个作业
- (b) 按最短作业优先次序运行
分析周转时间:
- 图a中,A的周转时间为8分钟,B为12分钟,C为16分钟,D为20分钟;平均周转时间=14分钟
- 图b中,A、B、C、D的周转时间分别为20、4、8、12分钟;平均周转时间=11分钟
最短作业优先算法在所有作业同时可用的情况下时最优的(最短的平均周转时间)。如果作业不是同时到达则不一定,看下面反例。
一个反例,假设有5个作业,A到E,运行时间分别为2,4,1,1,和1;到达时间分别为0,0,3,3和3。
按照最短作业优先算法调度:起初,只能选择A和B,因为另外三个作业尚未到达。使用最短作业优先将按照A,B,C,D,E的次序运行,其平均等待时间为4.6。
其他调度顺序:B,C,D,E,A的次序运行,其平均等待时间只有4.4。
因此,该方法只有在已知每个作业的运行时间以及所有作业同时到达才能拿使用。
分析
最短作业优先:

A的周转时间2;B的周转时间:2+4;C的周转时间:2+4+1+-3;D的周转时间:2+4+1+1-3;E的周转时间:2+4+1+1+1-3,平均周转时间:4.6
其他调度次序:

分析:A的周转时间4+1+1+1+2;B的周转时间4;C的周转时间:4+1-3;D的周转时间:4+1+1-3;E的周转时间:4+1+1+1-3;平均周转时间4.4
最短剩余时间优先(Shortest Remaining Time Next)
交互式系统的调度
时间片轮转调度(round robin)
抢占式算法
最古老、最简单、最公平且使用最广的算法时时间片轮转调度(round robin)。每个进程被分配一个时间段,称为其时间片(quantum),即该进程孕育运行的时间。
如果该进程在时间片结束时还在运行,则CPU将被强占并分配给另一个进程。如果改进程在时间片结束前阻塞或结束,则CPU立即切换。
实现:系统维护一个就绪进程队列。新作业到来时,被放置在就绪队列尾部。阻塞态或运行态的进程转入就绪态时,就像新到达的作业一样,被放在队列的尾部。

- (a) 可运行进程列表
- (b) 进程B用完时间片的列表排序
例题:进程A、B、C按顺序进入就绪队列,设它们进入队列的时间都是时刻0,它[们分别需要运行11、6、3ms。设时间片的大小为4ms。则运行过程如下图,平均周转时间是\(\frac {20+17+11} 3 = 16ms\)

设时间片的大小是2ms,则运行过程如下图,平均周转时间是\(\frac {20+15+11} 3 = 15.3ms\)

设计问题:时间片的大小
- 时间片太短:将导致过多的进程切换,降低CPU效率
- 时间片太长:有可能引起短的交互请求的响应时间变长
优先级调度(priority scheduling)
优先级调度其基本思想非常简明:每个进程被赋予一个优先级,优先级最高的可运行进程被允许进行。
存在静态或动态优先级
例子:

(采用静态优先级,设6是最高优先级)
立即抢占的优先级调度(优先级相同时采用FCFS)
调度原则:
调度程序从就绪队列中选择优先级最高的进程运行,当有优先级更高的进程到达时,则当前运行进程让出CPU(像新到进程一样重新在就绪队列中排队),否则一直运行到结束。
进程在就绪队列中按优先级排队,优先级相同时,按到达就绪队列时间排队。

周转时间:A:60-0=60;B:6-2=4;C:40-5=35;D:62-8=54;E:32-16=16
平均周转时间:(60+4+35+54+16)/5=33.8
非抢占式的优先级调度
调度原则:
- 调度程序从就绪队列中选择优先级最高的进程运行,一旦把CPU分配给一个线程,则此进程一直运行到结束,即使期间有更高级别的进程到达。
- 进程在就绪队列中按优先级排队,优先级相同时,按到达就绪队列时间排队。

周转时间:
A:32-0=32;B:36-2=34;C:60-5=55;D:62-8=54;E:54-16=36
平均周转时间:(32+34+55+54+36)/5=42.2
可以将进程按分组成若干优先级类,在各类之间采用优先级调度,而各类进程内部采用时间片轮转调度。下图显示了一个有4类优先级的系统,调度算法如下:只要存在优先级为4的可运行进程,就按照循环方式使其每个进程运行一个时间片,根本不理会较低优先级的进程。若第4类优先级进程为空,则以循环方式运行第三类进程。若第4、第3类均为空,则按循环法运行第2类进程,以此类推。

有4个优先级的调度算法
多级队列(multiple queues)
CTSS系统调度的设计:
- MIT在IBM7094机上开发的兼容分时系统
- 最早使用优先级调度的系统之一
- 内存只能存放一个进程,导致进程切换速度慢——当进程换出到磁盘,从磁盘读入新进程到内存
CTSS系统调度的设计
- 减少进程切换开销——长时间片
- 长时间片影响响应时间——动态时间片(设立优先级类,不同类时间片不同)
- 最高优先级类——1个时间片
- 次高优先级类——2个时间片
- 再次一级——4个时间片
- ……
- 进程初始属于最高优先级,用完所分配的时间片后被移到下一级,即优先级降低,但时间片变长
例子
一个进程需要连续计算100个时间片。它最初被分配一个时间片,然后被换出到磁盘(CTSS系统内存只能存放一个进程)。下一次运行将获得两个时间片,接下来分别时4、8、16、32、64(只是用了其中的37个)个时间片。因此该进程共需要7此交换(包括最初的装入),而采用纯粹的时间片轮转则需要100此交换。而且随着进程的优先级不断降低,运行频度逐渐放慢,从而为短的交互进程让出CPU。
最短进程优先(shortest process next)
对于批处理系统,由于对端作业优先总是可以产生最小的平均响应时间,如果它同样可以用于交互式系统,将是一件好事。作为一个特定的扩展,确实可以做到。交互式进程通常遵循“等待命令、执行命令、等待命令、执行命令”等等这样的模式,如果我们把每条命令的执行视为单独的“作业”,那么我们可以通过优先运行最短的进程使总的响应时间减到最小。
唯一的问题就是如何分辨出当前可运行进程中哪一个时最短的。
基于进程过去的行为做出估计,并且按照最短的估计运行时间运行进程。设某中断上的命令估计运行时间时\(T_0\),现测出它实际运行时间是\(T_1\),利用两个值的加权和来改进估计时间:
若设定\(\alpha = \frac 1 2\),可以得到后续的估算公式:
特点:
- 基于进程过去的行为做出估计
- 经过三次新的运行之后,\(T_0\)的权重在新的估计值中降到了\(\frac 1 8\)
- 这种通过一系列当前和先前的测量值的加权平均来估算下一个值的计数称为老化(aging)

浙公网安备 33010602011771号