操作系统(三)——处理机管理

在多道程序环境下,主存中有着多个进程,其数目往往多于处理机数目。这就要求系统能按某种算法,动态地把处理机分配给就绪队列中的一个进程,使之执行。分配处理机的任务是由处理机调度程序完成的。

处理机调度的层次

高级调度

高级调度(High Level Scheduling)又称为作业调度或长程调度(LongTerm Scheduling)。
高级调度是根据某种算法,把外存上处于后备队列中的那些作业调入内存

作业(job)

作业是一个比程序更为广泛的概念,它不仅包含了通常的程序和数据,而且还应配有一份作业说明书,系统根据该说明书来对程序的运行进行控制。在批处理系统中,是以作业为基本单位从外存调入内存的。

作业控制块(JCB,job control block)

为了管理和调度作业,在多道批处理系统中为每个作业设置了一个作业控制块,如同进程控制块是进程在系统中存在的标志一样,它是作业在系统中存在的标志,其中保存了系统对作业进行管理和调度所需的全部信息。每当作业进入系统时,系统便为每个作业建立一个JCB,根据作业类型将它插入相应的后备队列中。

作业调度

作业调度的主要功能是根据作业控制块中的信息,审查系统能否满足用户作业的资源需求,以及按照一定的算法,从外存的后备队列中选取某些作业调入内存,并为它们创建进程、分配必要的资源。然后再将新创建的进程插入就绪队列,准备执行。

低级调度

通常也把低级调度(Low Level Scheduling)称为进程调度或短程调度(ShortTerm Scheduling),它所调度的对象是进程(或内核级线程)。进程调度是最基本的一种调度,在多道批处理、分时和实时三种类型的OS中,都必须配置这级调度。

进程调度的三个基本机制

排队器、分派器(分配程序)、上下文切换机制。

进程调度的方式

(1)非抢占方式(nonpreemptive mode)
a. 定义:一旦把处理机分配给某个进程,无论该进程要运行多长时间,都不会因为其他原因而被抢占正在运行进程的处理机。直至该进程完成,自愿释放处理机。
b.优缺点:优点是实现简单,系统开销小,适用于大多数的批处理系统环境。但它难以满足紧急任务的要求——立即执行。
(2)抢占方式(preemptive mode)
a. 定义:根据某种原则去暂停某个正在执行的进程,将已分配给该进程的处理机重新分配给另一进程。
b. 优缺点:优点是,可以防止一个长进程长时间占用处理机,能为大多数进程提供更公平的服务,特别是能满足对响应时间有着较严格要求的实时任务的需求。但抢占方式比非抢占方式调度所需付出的开销较大。
c. 抢占调度方式遵循的原则

  • 优先权原则。通常是对一些重要的和紧急的作业赋予较高的优先权。
  • 短作业(进程)优先原则。短作业(进程)可以抢占当前较长作业(进程)的处理机。
  • 时间片原则。各进程按时间片轮流运行,当一个时间片用完后,便停止该进程的执行而重新进行调度。

中级调度

中级调度(Intermediate Level Scheduling)又称中程调度(Medium-Term Scheduling)。中级调度就是存储器管理中的对换功能。

调度队列模型和调度准则

调度队列模型

仅有进程调度的调度队列模型

具有高级和低级调度的调度队列模型

在批处理系统中,一般作业调度和进程调度都存在,作业调度按照一定的作业调度算法,从外存的后备队列中选择一批作业调入内存,并为他们创建进程,送入就绪队列;而进程调度按照进程调度算法,选择一个进程,将处理机分配给该进程

就绪队列的形式:在批处理系统中,最常用的是最高优先权优先调度算法,相应地,最常用的就绪队列形式就是优先权队列。其实可以是队列形式,也可以是无序链表形式。

同时具有三级调度的调度队列模型

调度算法

在OS中调度的实质是一种资源分配,因而调度算法是指:根据系统的资源分配策略所规定的资源分配算法。
批处理系统中,为了照顾为数众多的短作业,应采用短作业优先的调度算法;又如在分时系统中,为了保证系统具有合理的响应时间,应采用轮转法进行调度。

FCFS(first come first service,先来先服务)

FCFS既可用于作业调度,也可用于进程调度。FCFS比较利于长作业(或进程),而不利于短作业(或进程)。
缺点:由下面的带权周转时间的公式也可以看出,对于短作业(或进程),其服务时间比较短,则其带权周转时间就会很大,这是不能容忍的。

短作业(或进程)(SJ(P)F,short job(process) first)优先

SJ(P)F是指对短作业或短进程优先调度的算法,这里的“短”是估计的运行时间最短。
缺点:
该算法能有效降低短作业(或进程)的等待时间,但对长作业(或进程)不利。更可能导致长作业长期不会被调用;由于短作业(或进程)只是根据用户提供的估计运行时间而定,但估计也不一定准确。

高优先权优先(FPF,first priority fist)调度算法

当把该算法用于作业调度时,系统将从后备队列中选择若干个优先权最高的作业装入内存。当用于进程调度时,该算法是把处理机分配给就绪队列中优先权最高的进程。
(1) 优先权调度算法的类型
a. 非抢占式优先权算法:主要用于批处理系统中,和对实时性要求不严的实时系统中。
b. 抢占式优先权算法:主要用于比较严格的实时系统中,和对性能要求较高的批处理和分时系统中。
(2) 优先权类型
a. 静态优先权:在创建进程时确定的,且在进程的整个运行期间保持不变。
确定静态优先权的依据:

  • 系统进程(如接收进程、对换进程、磁盘I/O 进程)的优先权高于一般用户进程的优先权。
  • 对估计的运行时间和内存需求量少的进程应赋予较高的优先权。

b. 动态优先权:在创建进程时所赋予的优先权,是可以随进程的推进或随其等待时间的增加而改变的,以便获得更好的调度性能。

高响应比优先调度算法

在批处理系统中,短作业优先算法是一种比较好的算法,其主要的不足之处是长作业的运行得不到保证。如果我们能为每个作业引入动态优先权,并使作业的优先级随着等待时间的增加而以速率a 提高,则长作业在等待一定的时间后,必然有机会分配到处理机。

$$
优先权 = \frac{周转时间}{服务时间} = \frac{等待时间+服务时间}{服务时间} = \frac{响应时间}{服务时间} = 响应比
$$

由上式可以看出:

  • 如果作业的等待时间相同,则要求服务的时间愈短,其优先权愈高,因而该算法有利于短作业。
  • 当要求服务的时间相同时,作业的优先权决定于其等待时间,等待时间愈长,其优先权愈高,因而它实现的是先来先服务。
  • 对于长作业,作业的优先级可以随等待时间的增加而提高,当其等待时间足够长时,其优先级便可升到很高,从而也可获得处理机。

简言之,该算法既照顾了短作业,又考虑了作业到达的先后次序,不会使长作业长期得不到服务。

基于时间片的轮转调度算法

分时系统中,为保证能及时响应用户的请求,必须采用基于时间片的轮转式进程调度算法。
(1) 时间片轮法(round robin,RR)
a. 基本原理:在早期的时间片轮转法中,系统将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时,把CPU 分配给队首进程,并令其执行一个时间片。时间片的大小从几ms 到几百ms。当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。使得系统能在给定的时间内响应所有用户的请求。
b. 时间片大小的确定:当时间片太小,将有利于短作业,但频换切换开销大;如果时间片太长,使得每个进程都能在一个事件片内完成,则时间片轮转算法退化为先来先服务调度算法。
时间片大小最好是一个时间片略大于一次典型交互所需要的时间。
c. 例:进程A、B、C、D需要运行的时间分别为20ms、10 ms、15 ms、5 ms,均在0时刻到达。到达的先后次序为A、B、C、D。如果时间片分别为1ms和5ms,计算各个进程的带权周转时间和平均带权周转时间。
解:采用时间片轮转法进行调度,算法的性能指标如下:

进程名 到达时间 运行时间 开始时间 完成时间 周转时间 带权周转时间
时间片=1 A 0 20 0 50 50 2.5
B 0 10 1 34 34 3.4
C 0 15 2 45 45 3.0
D 0 5 3 20 20 4.0
平均周转时间=37.25 平均带权周转时间=3.225
时间片=5 A 0 20 0 50 50 2.5
B 0 10 5 30 30 3.0
C 0 15 10 45 45 3.0
D 0 5 15 20 20 4.0
平均周转时间=36.25 平均带权周转时间=3.125

(2) 多级反馈队列调度算法
前面介绍的各种用作进程调度的算法都有一定的局限性。如短进程优先的调度算法,仅照顾了短进程而忽略了长进程,而且如果并未指明进程的长度,则短进程优先和基于进程长度的抢占式调度算法都将无法使用。而多级反馈队列调度算法则不必事先知道各种进程所需的执行时间,而且还可以满足各种类型进程的需要,因而它是目前被公认的一种较好的进程调度算法。
a. 实施过程

  • 设置多个就绪队列,并为各个队列赋予不同的优先级,第一个就绪队列的优先级最高,后面的队列优先级逐个降低。赋予各个队列中进程执行时间片的大小也各不相同,在优先权越高的就绪队列中,时间片越小。
  • 当一个新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则排队等待调度。当轮到该进程执行时,如它能在该时间片内完成,便可准备撤离系统;如果它在一个时间片结束时尚未完成,调度程序便将该进程转入第二队列的末尾,再同样地按FCFS原则等待调度执行。即将长作业分解为短作业,以此类推。
  • 仅当第一队列空闲时,调度程序才调度第二队列中的进程运行;仅当第1~(i-1)队列均空时,才会调度第i队列中的进程运行。

b. 多级反馈队列调度算法性能:多级反馈队列调度算法具有较好的性能,能很好地满足各种类型用户的需要。

  • 终端型作业用户。由于终端型作业用户所提交的作业大多属于交互型作业,作业通常较小。
  • 短批处理作业用户。对于很短的批处理型作业,开始时像终端型作业一样,如果仅在第一队列中执行一个时间片即可完成,便可获得与终端型作业一样的响应时间。对于稍长的作业,通常也只需在第二队列和第三队列各执行一个时间片即可完成,其周转时间仍然较短。
  • 长批处理作业用户。对于长作业,它将依次在第1,2,…,n 个队列中运行,然后再按轮转方式运行,用户不必担心其作业长期得不到处理。

实时调度

前面介绍的多种算法不能很好地满足实时系统对调度的要求,因此引入了实时调度。
硬实时任务和软实时任务:硬实时任务指必须满足最后期限的限制,否则会给系统带来不可接受的破坏或者致命错误。软实时任务也有一个与之关联的最后期限,并希望能满足这个期限的要求,但这并不是强制的,即使超过了最后期限,调度和完成这个任务仍然是有意义的。

实现实时调度的条件

(1) 提供必要的信息。如就绪时间、开始截止时间和完成截止时间、处理时间、资源要求、优先级。
(2) 系统处理能力强。在实时系统中,通常都有着多个实时任务。若处理机的处理能力不够强,则有可能因处理机忙不过来而使某些实时任务不能得到及时处理,从而导致发生难以预料的后果。
(3) 采用抢占式调用机制。在含有硬实时任务的实时系统中,广泛采用抢占机制。当一个优先权更高的任务到达时,允许将当前任务暂时挂起,而令高优先权任务立即投入运行,这样便可满足该硬实时任务对截止时间的要求。但这种调度机制比较复杂。
(4) 具有快速切换机制。

常用的两种种实时调度算法

(1) 最早截止时间优先(earlist deadline first,EDF)算法
根据任务的开始截止时间来确定任务的优先级。开始截止时间愈早,其优先级愈高。
该算法既可用于抢占式调度,也可用于非抢占式调度方式中。

  • 非抢占式调度方式用于非周期实时任务。
  • 抢占调度方式用于周期实时任务。

(2) 最低松弛度优先(least laxity first,LLF)算法
根据任务紧急(或松弛)的程度,来确定任务的优先级。任务的紧急程度愈高,为该任务所赋予的优先级就愈高,以使之优先执行。松弛程度就是说该任务为了在给定某个时间前必须完成,至少需要在哪个时间点开始执行,因此松弛度低的任务排在队列前面。
该算法主要用于抢占调度方式中。

产生死锁的原因和必要条件

死锁(Deadlock),是指多个进程在运行过程中因争夺资源而造成的一种僵局(DeadlyEmbrace),当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。

产生死锁的原因

(1) 竞争资源
当系统中供多个进程共享的资源如打印机、公用队列等,其数目不足以满足各个进程的需要时,会引起各个进程对资源的竞争而产生死锁。
(2) 进程间推进顺序非法。
进程在运行过程中,请求和释放资源的顺序不当,也同样会导致产生进程死锁。如前面的wait和signal操作。
可剥夺资源和不可剥夺资源:可剥夺资源是指,某进程在获得这类资源后,该资源可以再被其他进程或系统剥夺。CPU和主存均属于可剥夺性资源。不可剥夺性资源是指,当系统把这类资源分配给某进程后,再不能强行收回,只能在进程用完后自行释放,如磁带机、打印机等。

产生死锁的必要条件

(1)互斥条件:在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求该资源,则请求者只能等待,直至占有该资源的进程用毕释放。
(2)请求和保持条件:指进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
(3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
(4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,…,Pn}中的P0正在等待一个P1占用的资源; P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

处理死锁的基本方法

(1)预防死锁破坏产生死锁的四个必要条件2、3、4中的任意一个或多个(条件1是设备的固有属性决定的,应该加以保证),来预防发生死锁.
(2)避免死锁。在资源的动态分配过程中,用某种方法去防止系统进入不安全状态,从而避免发生死锁。
a. 安全状态:是指系统能按某种进程顺序(P1,P2,…,Pn)(称〈P1,P2,…,Pn〉序列为安全序列),来为每个进程Pi分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都可顺利地完成。如果系统无法找到这样一个安全序列,则称系统处于不安全状态。
b.不安全状态转为进入死锁状态;但只要系统处于安全状态,系统便可避免进入死锁状态。
c. 安全状态序列例题:在当前时刻存在一个下次给进程分配资源的序列,使得下次分配的时候,能满足每个进程的资源需求。
d. 利用银行家算法避免死锁

(3)检测和解除死锁。允许系统在运行过程中发生死锁。但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源;然后,须将进程从死锁状态中解脱出来。常用的实施方法是撤消或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。