操作系统 并发:死锁和饥饿 复习题&练习题&总结

来源:互联网 发布:win qt 串口编程 编辑:程序博客网 时间:2024/04/27 21:48

Part1 复习题:

6.1可重用资源:处理器、I/O通道,贮存和辅存,设备以及诸如文件,数据库和信号量之类的数据结构。

        可消费资源:中断、信号、消息和I/O缓冲区的信息。

6.2产生死锁的3个必要条件:互斥、占有且等待、非抢占。

6.3产生死锁的4个条件:互斥、占有且等待、非抢占、循环等待。

6.4预防占有等待的条件:可以要求进程一次性的请求所有需要的资源,并且阻塞这个资源直到所有请求都同时满足。

6.5防止抢占条件的两种方法:

     第一种,如果占有某些资源的一个进程进行进一步资源请求被拒绝,则该进程必须释放它最初占用的资源,如果必要,可再次请求这些资源另外的资源。

     第二种,如果一个进程请求当前被另一个进程占有的一个资源,则操作系统可以抢占另一个进程,要求它释放资源。

6.6 预防循环等待的条件:

      可以通过定义资源类型的线性顺序来预防。如果一个进程已经分配到R类型的资源,那么它接下来请求的资源只能是那些排在R类之后的资源类型。

6.7死锁避免、检测和预防之间的区别:

    死锁预防是通过间接的限制3种死锁必要条件的至少一个或者是直接地限制循环等待的发生来避免死锁的出现。     死锁避免允许可能出现的必要条件发生,但是采取措施确保不会出现死锁的情况。

    死锁检测允许资源自由分配,采取周期性的措施来发现并处理可能存在的死锁情况。


Part 2  练习题

6.1举例说明死锁的4个条件:

    互斥:同一时刻只有一辆车可以占有一个十字路口象限。

    占有且等待:没有车可以倒退;在十字路口的每辆车都要等待直到它前面的象限是空的。

    非抢占:没有汽车被允许挤开其他车辆。

    循环等待:每辆汽车都在等待一个此时已经被其他车占领的十字路口象限。

6.2对于图6.1:

   死锁预防-互斥:。。。

   死锁预防-占有且等待:每辆车都顺次需要占用两个象限的资源。任意3辆车同时出发时不会出现死锁(但容易发生事故,O(∩_∩)O~)。在车辆速度相同的情况下,3辆车同时出发不会导致死锁和资源申请被拒。

   死锁预防-不可抢占:若执行上述预防占有且等待的方法,第四辆车出发前,接下来申请其首次申请资源的车辆需抢占该资源,否则发生死锁。

   死锁避免:

   资源总量:[a,c,b,d]=[1,1,1,1];进程i对资源j的需求:如图Cij=


             

    (1)进程启动拒绝:每种资源总的请求量都是2,若4个进程同时请求资源,则不满足关系式Cij<=Ri等。

       Rj=Vj+∑Aij,即对所有j 所有资源或者可用,或者已近被分配。

       Cij<=Ri,对所有i,j 任何一个进程对任何一种资源的请求都不能超过系统中该种资源的总量。

       Aij<=Cij,分配给任何一个进程的任何一种资源都不会超过该进程最初声明的此资源的最大请求个数。

        满足以上条件,且 条件满足时,启动新进程Pn+1,即只有所有当前进程的最大请求加上新的进程请求可以满足可以满足时,才会启动该进程。

        但是该条件很难最优,对于该题十字路口,每次只允许平行车道上的两辆车同行则满足要求,但不是最优结果。(最优解不一定是最适合的解)

   (2)资源分配拒绝(银行家算法)

        安全状态:至少有一个资源分配序列不会导致死锁。启动一个进程只需要分配其所需的第一资源。至少有一辆车分配到所有所需资源即可保持无死锁。

6.3 图6.2描述

    1.Q获得B和A,然后释放B和A。当P恢复执行时,获得全部资源。

    2.Q获得B和A,P阻塞在对A的请求上;Q释放B和A。当P恢复时,可以获得全部资源。

    3.Q获得B,然后P获得A再释放A,Q获得A后释放所有资源。

    。。。。。。对称

6.4 (1)死锁产生的四个必要条件:互斥,占有且等待,不可抢占,循环等待。

    (2)十字路口:

6.6死锁检测的应用:

    W=(2 1 0 0) ;Mark P3: W = (2 1 0 0)+(0 1 2 0)=(2 2 2 0)

                 Mark P2: W = (2 2 2 0)+(2 0 0 1)=(4 2 2 1)

                 Mark P1: W = (4 2 2 1)+(0 0 1 0)=(4 2 3 1) 没有死锁


        

       


总结:

1.死锁基本概念:

(1)理解:

以下內容為轉載:原文出自新浪愛問

操作系统中有若干进程并发执行, 它们不断申请、使用、释放系统资源,虽然系统的进 
程协调、通信机构会对它们进行控制,但也可能出现若干进程都相互等待对方释放资源才能 
继续运行,否则就阻塞的情况。此时,若不借助外界因素, 谁也不能释放资源, 谁也不能解 
除阻塞状态。根据这样的情况,操作系统中的死锁被定义为系统中两个或者多个进程无限期 
地等待永远不会发生的条件,系统处于停滞状态,这就是死锁。 
产生死锁的原因主要是: 
(1) 因为系统资源不足。 
(2) 进程运行推进的顺序不合适。 
(3) 资源分配不当等。 
如果系统资源充足, 进程的资源请求都能够得到满足,死锁出现的可能性就很低, 否则 
就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。 
产生死锁的四个必要条件: 
(1) 互斥条件:一个资源每次只能被一个进程使用。 
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。 
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。 
这四个条件是死锁的必要条件, 只要系统发生死锁, 这些条件必然成立, 而只要上述条件之 
一不满足,就不会发生死锁。 
 
死锁的解除与预防: 
理解了死锁的原因, 尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和 
解除死锁。所以, 在系统设计、进程调度等方面注意如何不让这四个必要条件成立, 如何确 
定资源的合理分配算法, 避免进程永久占据系统资源。此外, 也要防止进程在处于等待状态 
的情况下占用资源。因此,对资源的分配要给予合理的规划。

(2)死锁预防&死锁避免&死锁检测

死锁预防:间接死锁预防(阻止必要条件中任何一个的发生) & 直接死锁预防(防止循环等待)

死锁避免:允许必要条件发生,但通过选择防止到达死锁点,较预防允许更多并发。

          进程启动拒绝 & 资源分配拒绝(银行家算法)。

          优点:无需抢占、回滚。缺点:需声明最大资源;进程需无关;分配资源数目固定;占有资源不退出。

死锁检测:

         操作系统周期性地执行算法检测循环等待条件。如图:

        由于P4没有以分配的资源,标记P4--->临时向量W=(0 0 0 0 1)-->进程P3的请求小于或等于W,标记P3,令W=W+(0 0 0 1 0)=(0 0 0 1 1)--->没有其他未标记的进程在Q中小于或等于W,因此终止算法。 P1和P2没有标记,表示这两个进程死锁。

       死锁恢复:1)取消所有死锁进程。2)回滚和重启。3)基于最小代价取消死锁进程,检测。

2两个算法:

   (1)银行家算法:死锁避免--资源分配拒绝

以下来自维基:

 Allocation   Max   Available   ABCD  ABCD  ABCD P1 0014  0656  1520  P2 1432  1942  P3 1354  1356 P4 1000  1750

我们会看到一个资源分配表,要判断是否为安全状态,首先先找出它的Need,Need即Max(最多需要多少资源)减去Allocation(原本已经分配出去的资源),计算结果如下:

 NEED ABCD 0642  0510 0002 0750

然后加一个全都为false的字段

 FINISH false false false false

接下来找出need比available小的

   NEED  Available ABCD  ABCD 0642  1520 0510<- 0002 0750

P2的需求小于能用的,所以配置给他再回收

  NEED  Available ABCD  ABCD 0642  1520 0000 +1432 0002------- 0750  2952

此时P2 FINISH的false要改成true(己完成)

 FINISH false true false false

接下来继续往下找,发现P3的需求为0002,小于能用的2952,所以资源配置给他再回收

  NEED  Available ABCD  A B C D 0642  2 9 5 2 0000 +1 3 5 4 0002---------- 0750  3 12 10 6

同样的将P3的false改成true

 FINISH false true true false

依此类推,做完P4→P1,当全部的FINISH都变成true时,就是安全状态。

P - 进程的集合;Mp - 进程p的最大的请求数目;Cp - 进程p当前被分配的资源;A - 当前可用的资源

while (P != ∅) {    found = FALSE;    foreach (p ∈ P) {        if (Mp − Cp ≤ A) {             /* p可以獲得他所需的資源。假設他得到資源後執行;執行終止,並釋放所擁有的資源。*/             A = A + Cp ;             P = P − {p};             found = TRUE;        }    }    if (! found) return FAIL;}return OK;

   (2)哲学家就餐--解决死锁问题的其他方案

     

服务生解法

一个简单的解法是引入一个餐厅服务生,哲学家必须经过他的允许才能拿起餐叉。因为服务生知道哪只餐叉正在使用,所以他能够作出判断避免死锁。

为了演示这种解法,假设哲学家依次标号为A至E。如果A和C在吃东西,则有四只餐叉在使用中。B坐在A和C之间,所以两只餐叉都无法使用,而D和E之间有一只空余的餐叉。假设这时D想要吃东西。如果他拿起了第五只餐叉,就有可能发生死锁。相反,如果他征求服务生同意,服务生会让他等待。这样,我们就能保证下次当两把餐叉空余出来时,一定有一位哲学家可以成功的得到一对餐叉,从而避免了死锁。

资源分级解法

另一个简单的解法是为资源(这里是餐叉)分配一个偏序或者分级的关系,并约定所有资源都按照这种顺序获取,按相反顺序释放,而且保证不会有两个无关资源同时被同一项工作所需要。在哲学家就餐问题中,资源(餐叉)按照某种规则编号为1至5,每一个工作单元(哲学家)总是先拿起左右两边编号较低的餐叉,再拿编号较高的。用完餐叉后,他总是先放下编号较高的餐叉,再放下编号较低的。在这种情况下,当四位哲学家同时拿起他们手边编号较低的餐叉时,只有编号最高的餐叉留在桌上,从而第五位哲学家就不能使用任何一只餐叉了。而且,只有一位哲学家能使用最高编号的餐叉,所以他能使用两只餐叉用餐。当他吃完后,他会先放下编号最高的餐叉,再放下编号较低的餐叉,从而让另一位哲学家拿起后边的这只开始吃东西。

尽管资源分级能避免死锁,但这种策略并不总是实用的,特别是当所需资源的列表并不是事先知道的时候。例如,假设一个工作单元拿着资源3和5,并决定需要资源2,则必须先要释放5,之后释放3,才能得到2,之后必须重新按顺序获取3和5。对需要访问大量数据库记录的计算机程序来说,如果需要先释放高编号的记录才能访问新的记录,那么运行效率就不会高,因此这种方法在这里并不实用。

这种方法经常是实际计算机科学问题中最实用的解法,通过为分级锁指定常量,强制获得锁的顺序,就可以解决这个问题。

Chandy/Misra解法

1984年,K. Mani Chandy和J. Misra提出了哲学家就餐问题的另一个解法,允许任意的用户(编号P1, ..., Pn)争用任意数量的资源。与资源分级解法不同的是,这里编号可以是任意的。

    1. 对每一对竞争一个资源的哲学家,新拿一个餐叉,给编号较低的哲学家。每只餐叉都是“干净的”或者“脏的”。最初,所有的餐叉都是脏的。
    2. 当一位哲学家要使用资源(也就是要吃东西)时,他必须从与他竞争的邻居那里得到。对每只他当前没有的餐叉,他都发送一个请求。
    3. 当拥有餐叉的哲学家收到请求时,如果餐叉是干净的,那么他继续留着,否则就擦干净并交出餐叉。
    4. 当某个哲学家吃东西后,他的餐叉就变脏了。如果另一个哲学家之前请求过其中的餐叉,那他就擦干净并交出餐叉。

这个解法允许很大的并行性,适用于任意大的问题。


原创粉丝点击