490 likes | 645 Views
第八章 死锁处理. 主讲:陈笑蓉 贵州大学计算机科学与技术学院. 在多道程序系统中,多个进程并发运行,共享资源,从而提高了资源的利用率。 但是若对资源的管理和使用不当,在一定条件下会导致系统发生一种随机性故障 —— 死锁。 这时,若无外力协助,每个进程都不能继续执行下去。. 主要内容. 死锁的形成 资源分配图 死锁的排除方法 死锁的检测与解除. 8.1 死锁的形成. 这里讨论操作系统中的死锁问题不考虑: 进程申请根本就无法满足的系统资源(我要天上的智多星,否则我就不上课。可是天上根本就没有智多星!注定要失败!!);
E N D
第八章 死锁处理 主讲:陈笑蓉 贵州大学计算机科学与技术学院
在多道程序系统中,多个进程并发运行,共享资源,从而提高了资源的利用率。在多道程序系统中,多个进程并发运行,共享资源,从而提高了资源的利用率。 但是若对资源的管理和使用不当,在一定条件下会导致系统发生一种随机性故障——死锁。 这时,若无外力协助,每个进程都不能继续执行下去。
主要内容 • 死锁的形成 • 资源分配图 • 死锁的排除方法 • 死锁的检测与解除
8.1 死锁的形成 • 这里讨论操作系统中的死锁问题不考虑: • 进程申请根本就无法满足的系统资源(我要天上的智多星,否则我就不上课。可是天上根本就没有智多星!注定要失败!!); • 由于硬件故障或程序性错误引起的循环等待。 • 故可假设: • 任何进程要求的资源系统是可以满足的,它可以在有限时间内执行结束并归还系统资源; • 一个进程在申请资源暂时得不到满足时,处于等待资源的状态。
死锁——两个或两个以上进程都无限止等待永久不会出现的事件而发生的一种状态。死锁——两个或两个以上进程都无限止等待永久不会出现的事件而发生的一种状态。 • 陷入死锁状态的进程称为死锁进程,这样需要与它们进行某种合作的其它进程就会相继陷入死锁,最终可能导致整个系统处于瘫痪状态。 • 死锁涉及到两个或两个以上进程由于竞争资源引起的冲突。例如:
例1:再次考虑5个哲学家就餐问题 • 五个哲学家在一起思考和用餐。这些哲学家共用一张圆桌,周围放有五把椅子,每人座一张,在圆桌上有五个碗和五支筷子。当一个哲学家思考问题时,他不与同事交谈,饥饿时,便去试图取用其左右最靠近他的两支筷子,但他可能一支都拿不到,只有当他拿到两支筷子时才能用餐,用餐完毕,又将筷子放回原处,又继续思考。如何使这五个哲学家保持同步:既能进行思考又不至于饿死。
Begin Cobegin Pi (i=1,…,4) Begin L:思考; P(Si); 取Ri; P(Si+1); 取Ri+1; 用餐; 放回Ri和Ri+1; V(Si);V(Si+1); Goto L; End; P5 Begin L1:思考; P(S1); 取R1; P(S5); 取R5; 用餐; 放回R1和R5; V(S1);V(S5); Goto L1; End; Coend; End; Var S1,S2,S3,S4,S5:semaphore; S1,S2,S3,S4,S5 := 1,1,1,1,1;
发生进程死锁例子 P R1 R2 Q 例2,系统中只有一台打印机R1和一台读卡机R2,可供进程P和Q共享。假定P已占用了打印机R1,Q占用了读卡机R2,此时若Q继续要求打印机,P继续要求读卡机,则P与Q间便会形成僵局,两个进程都在等待着对方释放出自己所需的资源,但因它们都不能获得所需资源而不能继续推进,从而也不能释放出已占有的资源,以致进入死锁状态。
死锁形成原因: (1)竞争资源。为多个进程所共享的资源不足,引起它们对资源的竞争而产生死锁; (2)进程推进顺序不当。进程运行过程中,请求和释放资源的顺序不当,而导致死锁。 死锁涉及到资源的管理(分配策略)不当!
资源分类: • 按资源的占有方式 • 可剥夺资源——可剥夺资源是指资源占有者进程虽然仍然需要使用该资源,但另一进程却可以强行把资源从占有者进程处抢来,归自己使用。 • 不可剥夺资源——不可剥夺资源是指只有在占有者进程不再需要使用该资源而主动释放资源外,其它进程不得在占有进程使用资源过程中抢占。 • 一个资源是可剥夺资源还是不可剥夺资源,完全取决于资源的性质。 • 死锁与不可剥夺资源有关,竞争不可剥夺资源有可能会导致死锁。
按使用期限: • 永久资源——所有的硬件资源和可再入的纯代码过程,都属于可再次使用的永久资源,它们可被进程反复使用。 • 消耗性的临时资源——而在进程同步和通信情况中出现的消息、信号和数据也可看作资源,它们是属于消耗性的临时资源。 • 消耗性的临时资源同样也可能引起死锁。什么时候会发生死锁呢?
死锁的必要条件 • 系统出现死锁,则一定保持了如下四个必要条件,缺一不可。但即使这四个条件同时成立,却不一定导致死锁发生! • 互斥使用资源——资源独占使用 • 占有并等待资源——保持占有资源并等待其它资源 • 不可抢占资源——已经分配的资源不能被抢占 • 循环等待资源——环路等待(相互等待)
8.2 资源分配图RAG • 资源分配图 进程P申请1个R1的资源 R1 资源 进程 P 1个R1的资源被进程P占有
Holt(1972年)提出用资源分配图(Resources Allocation Graph)来建立产生死锁的4个必要条件的模型。 • 资源分配图RAG可以定义为一个二元组,即RAG=(V,E),其中V是顶点集,E是边集。 • V又包含两个子集合,V=(P,R),子集P={p1,p2,…pm}是进程集合,每个元素pi表示一个进程,在图中用圆圈表示;子集R={r1,r2,…rk}是资源集合,每个元素ri表示一类资源,在图中用方框表示,某类资源可能有多个分配单元,用方框中的小圆点表示。
边集中的边是有向边,可以是<pi,rj>或<rj,pi>,piP,rjR。边集中的边是有向边,可以是<pi,rj>或<rj,pi>,piP,rjR。 • 若<pi,rj>E,则表示在图中存在一条从节点pi指向节点rj的有向边,称作请求边,表示进程pi请求分配资源rj或rj中的一个单位; • 若<rj,pi>E,则在图中存在一条从节点rj指向节点pi的有向边,称作分配边,表示资源rj或rj中的一个单元已分配给了进程pi。
例如: 集合P、R和E: P={ p1,p2,p3}; R={r1,r2,r3,r4},其中r1有1个分配单元,r2有2个分配单元,r3有1个分配单元,r4有3个分配单元; E={<p1,r1>,<p2,r3>,<r1,p2>,<r2,p2>,<r2,p1>,<r3,p3>};
● ● r1 r3 P1 P2 P3 ● ● ● ● ● r2 r4
如上图使用资源分配图可以看出: • 如果资源分配图中无环路,则系统中没有死锁发生; • 资源分配图中有环是死锁产生的必要条件,而不是充分条件。
利用资源分配图判定死锁的基本法则: • 若RAG中未出现任何环路,则S为非死锁状态,或称安全状态; • 由若干单位资源构成的环路,是S为死锁状态的充分必要条件; • 由若干不全为单位资源构成的环路,是S为死锁的必要条件但非充分条件;
资源分配图的化简: • 对RAG图中不阻塞的非孤立进程结点,检查其申请的资源是否可以满足,若能满足,则删除其关联的所有分配边和申请边。 • 若能消去图中所有的边,使所有进程都能成为孤立结点,则称该图是可完全化简的;否则是不可完全化简的。 • 已经证明不同的化简顺序将会得到相同的化简图。 • 死锁定理:S是死锁的充分必要条件是S的状态资源分配图是不可完全化简的。
RAG化简算法: • 把某时刻的可用资源向量V(t)赋予资源数据向量W; • 把不占用资源的进程Li加入L; • 在进程集合中找Rj<=W的进程Pj ,作如下处理: • 删掉进程Pj的所有分配边和请求边并令L=L+{Pj}; • W=W+Aj(Aj是进程Pj的资源分配向量) • 重复步骤3直到不能再处理。 • 若L 不等于P,则G不可完全化简,否则已完全化简。
解决死锁的基本方法: (1)死锁预防。这种方法从死锁的四个必要条件出发,通过设置一些限制来破坏其中的至少一个条件,从而防止死锁的发生; (2)死锁避免。这种方法不是预先加上各种限制条件以预防产生死锁的可能性,而是允许有逼近死锁的可能性,但当接近死锁状态时,采取一些有效的措施加以避免,使死锁不至于最终发生; (3)死锁的检测及解除。它允许在系统运行过程中发生死锁,但一旦发生后便能立即检测出来,然后采取适当措施解除死锁。
8. 3 死锁的排除方法 • 破坏死锁成立的四个必要条件之一,就可以避免死锁。 死锁的必要条件: 防止死锁发生 互斥条件 允许多个进程同时访问资源 不可抢占条件 强迫进程暂时释放资源给其它进程 部分分配条件 “预先静态分配法” 循环等待条件 “有序资源使用法”
一、互斥条件 • 要使资源的互斥使用条件不成立,只有让进程可以共享同时使用资源,而资源的排它性使用是由资源自身的特性决定的。此路不通! 二、占有并等待 • 要破坏该条件,有两种方法: • 资源的静态分配 • 释放已占资源。
(一)资源的静态分配——预分配。是指进程要开始执行就一定已经获得其执行过程中所需要的全部资源;否则进程将分配任何资源而不执行。(一)资源的静态分配——预分配。是指进程要开始执行就一定已经获得其执行过程中所需要的全部资源;否则进程将分配任何资源而不执行。 显然,在进程执行过程中,不再申请任何资源,不需要去等待任何资源,故“占有并等待”条件不成立。 该策略实现简单,但具有重大的缺陷:系统的资源利用率非常低!即使有部分资源,或者就差一点点资源也不能执行。
(二)释放已占用资源——进程申请资源时刻前,必须先释放自己占用的全部资源。(二)释放已占用资源——进程申请资源时刻前,必须先释放自己占用的全部资源。 显然,系统中不会有任何进程它占有着资源同时还申请其它资源。因为进程要么只是占有资源而不申请资源,要么不占有资源而申请资源。故“占有并等待资源”不成立。
三、不可剥夺条件 • 如果进程A占有了某些资源而又要申请新资源r,而新资源r已经被其它进程B占用时,系统可以恰当地剥夺B的资源r给进程A。具体是:进程A申请资源时r, 1)如果资源r未被占用,则系统分配r给A; 2)如果r被B进程占有,则检查B的状态,若B是等待状态,则剥夺B的r资源给进程A;否则让A等待r资源。 3)一个等待资源的进程只有在得到自己所申请的新资源和所有被抢夺的旧资源后才能继续执行。 • 该策略不适合于某些资源,如打印机、磁带机,目前只适合于主存和处理器。
四、循环等待条件 采用按序分配策略 ,基本思想是:把系统中所有资源类型线性排队,并按递增规则赋予每类资源一个唯一的编号。例如输入机=1,打印机=2,磁带机=3等等。进程申请资源时,必须严格安资源编号的递增顺序进行,否则系统不予分配。可证明这种方法不会产生循环等待! 优点:资源的申请与分配是逐步进行的,与预分配策略比较,显著提高,但是实际上有些进程使用资源的顺序往往与系统规定的不一致,于是某些暂时不用的资源要先申请,先占住不使用,降低了系统资源利用率。
8.3.2 死锁避免 • 通过破坏死锁产生的必要条件来预防死锁是不好的解决死锁问题的方法。其限制条件使资源的利用率和进程的执行效率都大大降低。 • 但是,如果不采用预防死锁的策略来分配资源就不能确保系统中不出现死锁!所以,应该在估计到可能有死锁发生时就应想办法避免死锁的发生!每次申请资源时判断分配资源给进程是否安全,从而决定是否分配
安全状态:简单地说,系统中的所有进程都保证在有限的时间内总能得到需要的全部资源,就称系统处于“安全状态”。安全状态:简单地说,系统中的所有进程都保证在有限的时间内总能得到需要的全部资源,就称系统处于“安全状态”。 • 具体地说:安全状态指系统按某种进程顺序如<p1,p2,…,pn>,来为每个进程分配其所需资源,直至最大需求,使每个进程都可顺利完成。这时,称< p1,p2,…,pn>为安全序列。反之,若系统中不存在这样一个安全序列,则称系统处于不安全状态。系统就不安全。
系统处于安全状态就不会有死锁,否则可能发生死锁!系统处于安全状态就不会有死锁,否则可能发生死锁! • 避免死锁采取的策略就是避免分配资源导致系统进入不安全状态。 • 例如:P157
为了避免死锁的发生,就要求系统处于安全状态,于是,当有进程提出资源请求时,系统应分析这个进程已占资源数、尚需资源数、系统中可以分配的剩余资源数,然后决定是否为当前的申请者分配资源。为了避免死锁的发生,就要求系统处于安全状态,于是,当有进程提出资源请求时,系统应分析这个进程已占资源数、尚需资源数、系统中可以分配的剩余资源数,然后决定是否为当前的申请者分配资源。 • 如果能维持系统处于安全状态,则可为该进程分配资源,否则暂时不为申请者分配资源,直到有其它进程归还资源后再分配给它。
银行家算法 • 问题:银行家如何将总数一定的现金,安全地借给若干个客户,使得这些客户既能满足对资金的要求又能完成其交易,并且银行家可以收回自己的全部现金而不至于破产。 • 办法:如果每个客户的借款总额不超过银行的现金总数,而且在有限的期限内银行家可以收回借出的全部贷款,那么银行家就满足客户的借款要求,同客户进行借贷交易,否则银行家将拒绝贷款给客户。
银行家算法: • 假设系统中有n个进程,m类资源。数据结构: • 当前可用资源总数向量用A[ m ] • 最大需求矩阵用M [ n, m ] • 资源占用矩阵用U [ n, m ] • 剩余需求矩阵用N [ n , m ] • 关系:M[ i , j ]= U[ i , j ]+N[ i ,j ]
令RRi是进程Pi的资源请求向量, • (1)判断进程Pi申请的各类资源RRi是否大于它还需要的资源Ni,若RRi>Ni,则请求无效并作错误处理;否则,转下一步; • (2)判断进程Pi申请的各类资源RRi是否大于系统当前的可用资源A,若RRi>A,则说明系统当前的系统资源不能满足请求,则进程Pi必须等待;否则继续下一步; • (3)系统试着给进程Pi分配所需的资源:
进程Pi分配所需资源后,系统剩下的可用资源应减去RRi ,即A:=A-RRi;进程Pi现在占有的资源相应的增加RRi,即Ui:=Ui+RRi;进程还需要的资源自然减少RRi,即Ni:=Ni-RRi; • (4)调用安全算法检查修改后的现行状态是否安全。如果假分配后资源状态仍是安全的,就实施真分配以满足进程Pi的当前资源请求;否则系统拒绝分配,恢复假分配前的资源分配状态,并令进程Pi等待。
安全算法 : • 引入向量W(Work)用于记录系统可用资源和F(Finish)用于标记进程的执行情况 : (1)系统给进程真正分配资源前,可用资源就是系统当前可用的资源,故W:=A;开始时n个进程没有一个执行完成,故F[i]:=false(i=1,2,…,n); (2)寻找某个未执行完的进程Pi,系统能够满足它的资源请求,即F[i]=false且Ni≤W。如果不存在这样的进程,则转步骤(4);
(3)如果系统先满足进程Pi的资源需求,让它能够完成执行,在进程Pi完成执行之后,它所占有的资源就可以释放出来归还给系统,于是系统可用资源增加为W:=W+Ui,F[i]:=true,标记进程Pi可以完成执行;转步骤(2);(3)如果系统先满足进程Pi的资源需求,让它能够完成执行,在进程Pi完成执行之后,它所占有的资源就可以释放出来归还给系统,于是系统可用资源增加为W:=W+Ui,F[i]:=true,标记进程Pi可以完成执行;转步骤(2); (4)对任意的i(i=1,2,…,n),若F[i]=true,说明所有的进程都有可能完成执行,则现行状态是安全的,否则是不安全的。
3011 0100 1110 1101 0000 1100 0112 3100 0010 2110 A=(1,0,2,0) U= N= • 例如P158,系统有4类资源:磁带驱动器、绘图仪、打印机和穿孔机,分别用r1、r2、r3和r4表示,各类资源的总数用W=(6,3,4,2)表示,即有6台磁带驱动器、3台绘图仪、4台打印机和2台穿孔机。现有5个进程P1、P2、P3、P4和P5,已获得的资源种类和数量如下: • 假设进程p2当前请求向量RR2为(0,0,1,0)
由上可知,银行家算法确实能保证系统时刻处于安全状态,因而借助该算法来预测系统的安全性 !例如: 若系统有同类资源m个,可并发执行且共享该资源的进程数为n,而每个进程申请该资源的最大值为x(1<=x<=m),只要不等式 n(x-1)+1 <= m 成立,系统就一定不会发生死锁!
8.4 死锁的检测与解除 • 死锁预防的方案限制条件过于严格,降低了资源的利用率;而死锁避免的算法需要的信息有时又无法得到。 • 在一些系统中,考虑到死锁发生的可能性不会太大,对死锁不采取任何预防措施,对资源分配不加限制,也就是说让发生的死锁发生,在适时的时刻检测到死锁发生后再想办法解除
死锁检测 • 检测死锁的实质是确定是否存在环路等待现象。一旦发现这种环路便认定死锁存在。并识别出该环路涉及的有关进程,然后采取适当的措施来解除死锁。 • ① 在RAG中寻找这样的进程节点pi,它有分配边但无请求边,或有请求边但它的请求边可立即转换成分配边,换句话说,进程pi的资源请求可立即得到满足。若没有这样的进程pi,则转步骤③;
② 消去进程节点pi的所有分配边,使其成为孤立节点。转步骤 ①; ③如果RAG中所有的进程节点pi都是孤立节点,不存在任一环路,说明RAG是可完全化简的,根据死锁定理这表明系统中不存在死锁;否则RAG是不可完全化简的,因而存在死锁,所有不能完成执行的进程pj构成了一个环路,进程pj为死锁进程。
死锁解除 一旦检测到死锁,就要立即设法解除。死锁解除的方法一般有两种: • ①撤消进程法。 • 可以是撤消所有死锁进程,也可以逐个进行撤消,每撤消一个进程就检测死锁是否还存在,若不存在了,就停止撤消。撤消所有进程的方法比较武断。 • 逐个撤消的方法的关键问题是按什么顺序进行撤消,先撤消哪个进程,再撤消哪个进程。可以依据进程优先级进行撤消,优先级低的先撤消,优先级高的后撤消。 • 或者依据代价最小的原则,要求撤消路径最短,即按撤消路径所撤消的进程数最少。
②挂起进程法。使用挂起/激活机构挂起一些进程,剥夺它们占有的资源以解除死锁,待以后条件满足时,再激活被挂起的进程。问题是在挂起点激活比较困难,要退回到挂起点以前的某个状态重新执行,这需要维护进程执行日志,增大了系统开销。②挂起进程法。使用挂起/激活机构挂起一些进程,剥夺它们占有的资源以解除死锁,待以后条件满足时,再激活被挂起的进程。问题是在挂起点激活比较困难,要退回到挂起点以前的某个状态重新执行,这需要维护进程执行日志,增大了系统开销。
重点与难点 • 概念:死锁、死锁的必要条件、解决死锁的方法: • 死锁预防 • 死锁避免 • 死锁检测 • 产生死锁的检测等的具体应用 作业:1,3,5,6,7