【操作系统】知识梳理(三)处理机调度与死锁

3.1 处理机调度的基本概念

1.处理机调度的层次


一个作业从提交开始,往往要经历下述三级调度。
1)高级调度
高级调度又称为作业调度或长程调度。在批处理系统中,用户提交的作业先被存放在磁盘的后备队列中,高级调度用于决定把外存后备队列中的哪些作业调入内存,为它们分配必要的资源,.并创建进程。在批处理系统中,大多数配有作业调度,但在分时和实时系统中,却往往不配置作业调度。作业调度的运行频率较低,通常为几分钟一次。
2)低级调度
低级调度又称为进程调度或短程调度,用来决定就绪队列中哪个进程先获得处理机,并将处理机分配给选中的进程,让它投入执行。进程调度是最基本的调度,在三种类型的操作系统中都必须配置进程调度。进程调度的运行频率很高,典型的情况是几十毫秒运行一次,所以进程调度算法不能太复杂,以免占用太多的CPU时间。
进程调度的任务主要有保存当前进程的处理机现场,按照某种调度算法选取投入执行的新进程,以及把处理器分配给新进程三个方面。
进程调度可采取下述两种方式:
(1)非抢占方式。采用这种调度方式时,一.旦进程获得CPU,它将一 直执行,直至该进程完成或发生某事件而阻塞时,才将CPU分配给其他进程。这种方式的优点是简单、系统开销小,但它难以满足紧急任务的要求,故不适宜用于要求比较严格的实时系统中。
(2)抢占方式。采用这种调度方式时,当- -进程正在处理机.上执行时,系统可根据某种原则暂停它的执行,并将已分配给它的处理机重新分配给另一个进程。

抢占的原则有:
①优先权原则。就绪的高优先权进程有权抢占低优先权进程的CPU。
②短作业优先原则。就绪的短作业(进程)有权抢占长作业(进程)的CPU。
③时间片原则。一个时间片用完后,系统重新进行进程调度。
3)中级调度
中级调度又称为内存调度或中程调度,它按一-定 的算法将外存中已具备运行条件的进程换入内存,而将内存中处于阻塞状态的某些进程换至外存。中级调度的目的是解决内存紧张问题,它常用在分时系统及具有虚拟存储器的系统中。它的运行频率介于上述两种调度之间。


2.处理机调度的目标


调度方式和算法的选择取决于操作系统的类型及其目标,-般系统都要求调度能达到系统吞吐量大、处理机利用率高、各类资源能平衡利用以及对不同类型的作业具有公平性等目标。但是不同类型的系统通常还会有自己的要求,譬如,批处理系统希望周转时间短,分时系统要求响应时间快,而实时系统则要求能保证其截止时间等,因此它们将采用不同的调度方式和调度算法。

3.2 调度算法

1.先来先服务算法(FCFS)


该算法是一种最简单的调度算法,它既可用于作业调度,也可用于进程调度。在进程调度中采用FCFS算法时,将选择最先进入就绪队列的进程投入执行。FCFS算法属于非抢占调度方式,其特点是简单、易于实现,但不利于短作业和I/O型的作业的运行。FCFS算法很少作为进程调度的主算法,但常作为辅助调度算法。


2.短作业优先(SJF)


该算法既可用于作业调度,也可用于进程调度。短作业优先调度算法是选择就绪队列中估计运行时间最短的进程投入执行,它既可采用抢占方式,也可采用非抢占方式,抢占的SJF算法通常也叫作最短剩余时间优先算法。SJF算法能有效地缩短作业的平均周转时间,提高系统的吞吐量,但不利于长作业和紧迫作业的运行。由于估计的运行时间不一定准确,它不一定能真正做到短作业优先。


3.优先级调度算法(PSA)


该算法也是一种既可用于作业调度,也可用于进程调度的算法。在用于进程调度时,系统根据进程的紧迫程度赋予每个进程-一个优先权,并将选择就绪队列中优先权最高的进程投入执行。它既可采用抢占方式,也可采用非抢占方式。
进程优先权的设置通常分成静态和动态两种。
(1)静态优先权。静态优先权是指在创建进程时,根据进程的类型、进程对资源的要求和用户的要求等确定它的优先权,以后该优先权便不再变化。静态优先权法简单易行,.但随着进程的推进,其优先权可能与进程的情况不再相符。
(2)动态优先权。动态优先权是指在创建进程时所确定的优先权,可以随着进程的推进而改变。例如,可以规定:就绪进程的优先权,随着等待时间的增长以速度a增加;正在执行进程的优先权以速度b下降,这样既可避免一个低优先权的进程长期处于饥饿状态,又可防止一个长作业长期垄断处理机。


4.高响应比优先调度算法(HRRN)


该算法实际上是--种动态优先权调度算法,它以响应比作为作业或进程的动态优先权,其目的是既照顾短作业,又考虑到作业的等待时间,使长作业不会长期等待;但每次调度前,都要进行响应比的计算,会增加系统开销。


5.时间片轮转法(RR)


在分时系统中都采用时间片轮转算法进行进程调度。时间片是指一个较小的时间间隔,通常为10 ms~ 100 ms。在简单的轮转算法中,系统将所有的就绪进程按FIFO规则排成一个队列,将CPU分配给队首进程,且规定它最多只能连续执行一个时间片,若时间片用完时进程仍未完成,也必须将其插入就绪队列末尾,并把CPU交给下一个进程。时间片轮转法只用于进程调度它属于抢占调度方式其特点是简单易行、平均响应时间短,但它不利于处理紧急作业。


6.多级队列调度算法


多级队列调度算法将系统中不同类型或性质的就绪进程固定分配到不同的就绪队列中,每个就绪队列可采用自己的调度算法:而在队列之间,通常采用固定优先权的抢占调度方式。这种调度算法可针对不同用户进程的需求,提供不同的调度策略。


7.多级反馈队列调度算法(FB)


(1)在采用多级反馈队列调度算法的系统中,设置了多个不同优先级的就绪队列,并赋予各个队列大小不同的时间片,使优先级愈高的队列时间片愈小。
(2)新就绪的进程总是先进入第-级(即 最高优先级)队列的末尾,并按FCFS原则等待调度;当轮到该进程执行时,如它能在规定的时间片内完成,便可准备撤离系统,否则将它转入第二级队列末尾,再同样按FCFS原则等待调度;如果它在第二级队列上运行一个时间片后仍未完成,再依次将它转入第三级队列,...如此下去,当一个长作业从第一级队列降到最后一级队列时, 便在该队列中采取时间片轮转方式运行。
(3)系统总是调度第一级队列 上的进程执行,仅当第一级队列空时,才调度第二级队列上的进程执行。以此类推,仅当第1~(i- 1)级队列均空时,才调度第i级队列上的进程执行。.
多级反馈队列调度算法属于抢占调度方式,它能较好地满足终端型作业用户、短批处理作业用户和长批处理作业用户等各种类型用户的需要。

3.3 实时调度

1.实现实时调度的基本条件

实时系统中的任务通常都联系着一个截止时间,实时调度的关键是保证满足实时任务对截止时间的要求。
为了保证满足实时任务对截止时间的要求,实时系统必须具备足够强的处理能力和快速的切换机制。通常,在提交实时任务时,系统将该任务的截止时间、所需的处理时间、资源要求和优先级等信息一起提交给调度程序, 若系统能及时处理该任务,调度程序便接收该任务,否则,拒绝接收该任务。

2.实时调度方式和算法的选择

对不同的实时系统,其调度方式和算法的选择也各不相同。在一些小型实时系统或要求不太严格的实时控制系统中,常采用简单易行的非抢占式轮转调度方式,它仅可获得数秒至数十秒的响应时间;而在有一定要求的实时控制系统中,可采用非抢占式优先权调度算法,它仅可获得数秒至数百毫秒级的响应时间。在要求比较严格(响应时间为数十毫秒以下)的实时系统中,应采用比较复杂的抢占调度方式,其中,基于时钟中断的抢占式优先权调度算法,可获得几十毫秒至几亳秒的响应时间,可用于大多数的实时系统;而立即抢占的优先权调度算法,可将响应时间降到几毫秒至100微秒,甚至更低,适用于要求更严格的实时系统。


3.常用的几种实时调度算法


(1)最早截止时间优先(EDF)算法。EDF算法根据任务的开始截止时间来确定任务的优先级,即任务的开始截止时间愈早,其优先级愈高。在实现该算法时,要求系统中保一个实时任务就绪队列,该队列按各任务的截止时间的早晚排序。EDF算法既可采用非抢占调度方式,也可采用抢占调度方式。在采用抢占调度方式时,如果新到达的任务的开始截止时间比正在执行的任务早,则它将立即抢占CPU.
(2)最低松弛度优先(LLF)算法。LLF算法根据实时任务的松弛度(松弛度=任务必须完成的时间-任务本身的运行时间-当前时间)来确定任务的优先权,即任务的松弛度越低,其优先权越高。在实现该算法时,要求系统中有一个按松弛度排序的实时任务就绪队列。该算法通常采用抢占方式,当一任务的最低松弛度为0时,它便立即抢占CPU,以保证它的截止时间要求。

4.优先级倒置

优先级倒置指的是高优先级进程(或线程)被低优先级进程(或线程)延迟或阻塞的现象。例如,正在执行的进程A的优先级比较低,目前它已经进入与临界资源R相关的临界区内执行;此时,如果有一个优先权较高的进程B就绪,则B可以抢占A的CPU接着运行,如果B申请进入临界区内使用被A占用的临界资源R,则B进程进入阻塞状态,等A进程释放临界资源R。在这个阻塞过程中,考虑到很可能有某些优先权高于A但小于B的进程就绪,它们比A优先获得CPU,那么B被延长的时间更是不可预知和无法限定的。为了解决优先级倒置问题,当高优先级的B进程被低优先级的A进程阻塞时,可以让A进程暂时继承B进程的优先权,从而避免A进程被优先权高于A但低于B的进程抢占。 

3.4 死锁的基本概念 

如图3.1所示的系统,有一-台打印机R和一-台读卡机R2,供进程P1和P2共享。假定P1已占用打印机R,P2已占用读卡机R2。此时,若P2继续要求打印机,P1 要求读卡机,则P和P2间便会形成僵局,它们都在等待着对方释放出自己所需的资源,但同时又不可能释放出自己已占用的资源,从而进入死锁状态。


 

1.死锁的定义


一个进程集合中的每--个进程都在等待只能由该集合中的其他进程才能引发的事件,那么该组进程进入死锁状态(Deadlock)。由于集合中的每个进程都在等待集合中的另一个进程释放资源,但由于它们都已经处于等待状态而无法运行,所以它们谁也不会释放资源,结果是这组进程都将无法再向前推进。


2.产生死锁的原因

(1) 竞争资源。当系统中供多个进程共享的资源不足,而这些资源又属于不可抢占资源时,将引起进程对资源的竞争而产生死锁。在图3.1所示的实例中,由于打印机和读卡机的数量不足,而引起PI和P2进程对它们的竞争并进入了死锁状态。
(2)进程推进顺序非法。进程在运行过程中具有异步性特征,如果它们之间的推进顺序不当,也同样会导致进程产生死锁。在上面的例子中,若进程PI和P2按下述顺序推进:P申请(Ri)-→P1申请(R2)-→P1释放(R)-→P:释放(R2)-→+P2申请(R2)-→P2申请(Ri)→P2释放(R2)→P2释放(R1),则两个进程均可顺利完成,而不会进入死锁状态。

3.产生死锁的必要条件

(1) 互斥条件。进程所竞争的资源必须被互斥使用。
(2)请求与保持条件。当前已拥有资源的进程,仍能申请新的资源,而且,当该进程因新的资源被其他进程占用而阻塞时,它对自己已获得的资源仍保持不放。
(3)不剥夺条件。进程已获得的资源,只能在使用完时自行释放,而不能被抢占。
(4)环路等待条件。存在一个至少包含两个进程的循环等待链,链中的每个进程都正在等待下一个进程所占有的资源。

3.5 处理死锁的基本方法

1.预防死锁

预防死锁是通过破坏产生死锁的某个必要条件来防止死锁的发生。四个必要条件中,后三个条件都可被破坏,而第一一个条件,即“互斥”条件,对某些像打印机这样的设备,可通过Spooling 技术予以破坏,但其他资源,因受它们的固有特性的限制,不仅不能被破坏,反而应通过同步机制加以保证。
(1)摒弃“请求与保持”条件。要摒弃“请求与保持”条件,可规定所有进程都必须一次性申请其在运行过程中所需的全部资源。该方法虽然简单易行,但分配给一个进程的资源可能有相当长的一段时间没被使用,故易造成资源的严重浪费,而且,进程必须等待获得全部资源后才可开始运行,这又会导致进程迟迟不能运行。因此可将上述方法加以改进,允许一个进程只获得运行初期所需的资源后,便可开始运行:运行过程中,它可逐步释放已分配给自己的资源,当这些资源全部释放之后,它可以再次请求新的所需资源。改进后的方法不仅能提高资源的利用率,还能减少进程等待的时间,使它们更快地完成。
(2)摒弃“不剥夺”条件。要摒弃“不剥夺”条件,可规定一个已经保持了某些资源的进程,在提出新的资源请求而不能立即得到满足时,必须释放它已获得的所有资源。该方法实现起来比较复杂,且要付出很大代价,因为一个资源在使用一段时间后被释放,可能会造成前阶段工作的失效:而反复地申请和释放资源,又会使进程的执行无限推迟,从而进一步增加系统的开销,降低系统的吞吐量。
(3)摒弃“环路等待”条件。要摒弃“环路等待”条件,可将系统中的资源按类型赋予不同的序号,并规定所有的进程必须严格按照资源序号递增的顺序申请资源,这样,占据较低序号资源的进程可能等待占据较高序号资源的进程释放资源,但不可能存在反向的等待,因此,不会形成进程的循环等待链。这种方式的资源利用率和系统吞吐量都比前两种方式有显著的提高,其主要问题是:为方便用户编程,资源的编号必须相对稳定,这就限制了新设备类型的增加:另外,尽管在为资源类型分配序号时,已考虑到大多数进程实际使用这些资源的顺序,但仍有很多进程使用资源的顺序与系统规定的顺序不同,从而造成资源的浪费。

2.避免死锁

在预防死锁的几种方法中,都施加了较强的限制条件,而在避免死锁的方法中,所施加的限制条件较弱,因而,有可能获得令人满意的性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可避免死锁的发生。
1)安全与不安全状态
所谓安全状态,是指系统能按某种进程顺序,如<P,P2, .. P.>,来为每个进程分配其所需资源,直至最大需求,使每个进程都可顺利地完成,这样的序列<P,P2, .. Pn>被称为安全序列。若系统不存在这样-一个安全序列,则称系统处于不安全状态。
虽然并非所有不安全状态都将导致死锁状态,但当系统进入不安全状态后,便有可能进入死锁状态;反之,只要系统处于安全状态,系统便可避免进入死锁状态。因此,在避免死锁的方法中,允许进程动态地申请资源,并在每次分配资源时进行安全性检查,若此次分配不会导致系统进入不安全状态,便将资源分配给进程:否则,进程将进入等待状态。
2)利用银行家算法避免死锁
最有代表性的避免死锁的算法是Dijkstra 的银行家算法。为实现银行家算法,系统中必须设置若干数据结构,具体设置如下所述:
①可用资源向量Available。这是一个含有m个元素的数组,其中的每个元素代表一类可利用的资源数目(如Availablel[]=K,表示现在系统中可用的R类资源有K个)。
②最大需求矩阵Max。这是一个nx m的矩阵,它定义了系统中每个进程对m类资源的最大需求(如Maxfi. i]=K,表示进程i需要R;类资源的最大数目为K)。
③分配矩阵Allocation. 这是一个nx m的矩阵,它定义了系统中每个进程已分配到的各类资源的数目(如Allocation[ij]=K,表示进程i已获得K个R;类资源)。
④需求矩阵Need.这是--个nxm的矩阵,用来表示每个进程尚需的各类资源数(如Need[i,j]=K,表示进程i还需要R:类资源K个,方能完成任务)。
上述三个矩阵间存在着下述关系: 
Need[i, j] = Max[i.j] - Allocation[ij]
当P:进程发出资源请求Request;后,系统将按银行家算法来进行检查,并决定是否要将资源分配给P:进程。具体的银行家算法的描述如下:
①如果Request≤Need,则转向步骤②;否则认为出错,因为它所请求的资源已经超过实际的需要。
②如果Request;≤Available, 则转向步骤③;否则,表示尚无足够资源,进程P;必须等待。
③系统试探着把资源分配给进程P,并按下面的方式修改数据结构中的值:
Available[j] =Available[j] - Request:[j];
Allocation[ij] = Allocatin[ij] + Requet[i];
Need[ij] = Need[i, j] - Requesti[j];
④系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,则正式将资源分配给进程P,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程P:等待。
3)安全性算法
安全性算法的描述如下:
①设置两个工作向量:工作向量work,它含有m个元素,表示安全性检查过程中系统可提供给进程的各类资源数目,其初值等于Available; 工作向量Finish,它含有n个元素,表示系统是否有足够的资源分配给各个进程,使之运行完成, Finish[i]的初值均为false。
②从进程集合中找到一个能满足下述两个条件的进程:
Finish[i] = false;
Need;≤work;
如找到,则执行步骤③;否则,执行步骤④。
③当进程P;获得资源后,顺利执行,直至完成,并释放出分配给它的资源,故应执行:
work[j] = work[j] + Allocation[i, j];
Finish[i] = true;
转步骤②;
④如果所有进程的Finish[i]-true,则表示系统处于安全状态;否则系统处于不安全状态。

3.死锁的检测与解除

如果事先不采取措施来防止死锁的发生,则系统会存在死锁的可能,此时,系统必须提供死锁检测和解除的手段。
1)资源分配图
资源分配图是描述进程和资源间申请和分配关系的一一个有向图。图中的结点可分为进
程和资源两类,通常用圆圈代表一个进程结点,方框代表- -个 资源结点。由于一类资源可
能有多个,因此,常用方框中的一个点表示其中的一个资源。图中的边也可分成分配边和
请求边两类,分配边由资源结点指向进程结点,表示相应的--个资源已被分配给对应进程;
而请求边则是由进程结点指向资源结点,表示相应进程申请-一个对应的资源。
将既没有请求边也没有分配边与之相连的进程结点称作孤立结点。将有请求边,但目
前可用资源无法满足其要求的进程结点称作阻塞结点。
2)死锁定理
可通过将资源分配图简化的办法来检测系统状态S是否为死锁状态。简化方法为:在资源分配图中找一个既不阻塞又不孤立的进程结点Pi;系统可分配给它所需的资源,故它能够继续运行直至完成,再释放它所占用的资源,这相当于消去它的请求边和分配边,使之成为孤立点。重复上述简化的动作,若能消去所有的边,使所有进程都成为孤立结点,则称资源分配图是可以完全简化的;否则,就称该资源分配图是不可完全简化的。
有关文献证明所有的简化顺序将得到相同的结果。S状态为死锁状态的充分条件是:当且仅当S状态的资源分配图是不可完全简化的。该条件被称为死锁定理。
3)死锁的检测
检测死锁的一个常见算法描述如下(算法中Available、Allocation、 Request、 Work 的含
义与上一节相同,L为一初值为空的进程表):
①将不占有资源的进程(即Allocation;=0 的进程)记入L表中,并令Work等于Available。
②从进程集合中找-一个未记入L表中,并且Request≤Work的进程,若不存在这样的进程,则转步骤③;否则,将该进程记入L表中,增加工作向量Work = Work + Allocation,并重复执行步骤②。
③若不能把所有进程都记入L表中,则表示这些进程将发生死锁。
4)死锁的解除当发现有进程死锁时,应立即将它们从死锁状态中解脱出来。常用的两种方法是:
①剥夺资源。从其他进程剥夺足够数量的资源给死锁进程,以解除死锁状态。
②撤消进程。最简单和最常用的方法是撤消全部死锁进程:也可以按某种顺序逐个地撤消死锁进程,直至有足够的资源可用,使死锁状态清除为止。
处理死锁的每种方式都需要付出一定的代价, 并可能对用户作一些 不便的限制。因此,有些系统采用对死锁视而不见的鸵鸟算法,以求在效率和正确性之间进行折衷处理。如果死锁发生的频率非常低,这种处理方式是一种很明智的选择。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aaron_Liu0730

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值