第八章 死锁
1. 死锁、饥饿和活锁
死锁是指在多道程序中,一组进程中的每个进程均无期限的等待被该组进程中的另一个进程所占有且永远不会释放的资源。
饥饿是指一个可运行的进程尽管能继续执行,但被调度器无限期地忽视,而不能被调度执行的情况。饥饿可以通过先来先服务资源分配策略来避免。
活锁指的是任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试,失败,尝试,失败。
活锁和死锁的区别在于活锁的实体是在不断的改变状态,活锁有可能自行解开,死锁则不能。
2. 死锁产生的原因
产生死锁的原因主要有两个:
一是竞争资源,系统提供的资源数量有限,不能满足每个进程的需求;
二是多道程序运行时,进程推进顺序不合理。
3. 产生死锁的四个条件
1) 互斥条件
资源是独占的且排他使用。进程互斥使用资源,即任一时刻一个资源只能给一个进程使用,其他进程若请求一个资源而该资源被另一进程占有时,则申请者等待,直到资源被占用者释放。
2) 不可剥夺条件
又称不可抢占或不可强占。进程所获得的资源在未使用完毕之前,不能被其他进程强行剥夺,而只能由获得该资源的进程自愿释放。
3) 请求和保持条件
又称部分分配或占有申请。进程每次申请它所需要的一部分资源,在申请新的资源的同时,继续占用已分配到的资源。
4) 循环等待条件
又称环路等待。在发生死锁时,必然存在一个进程等待队列{ P1,P2,···, Pn},其中P1等待 P2 占有的资源,P2 等待 P3 占有的资源,…,Pn等待P1占有的资源,形成一个进程等待环路。环路中每一个进程已占有的资源同时被另一个进程所申请,即前一个进程占有后一个进程所请求的资源。
4. 死锁检测
操作系统可定时运行一个“死锁检测”程序,该程序按一定的算法去检测系统中是否存在死锁。
检测死锁的实质是确定是否存在“循环等待”条件,检测算法确定死锁的存在并识别出与死锁有关的进程和资源,以供系统采取适当的解除死锁措施。
5. 死锁预防
在设计系统时确定资源分配算法,限制进程对资源的申请,从而保证不发生死锁。
具体的做法是破坏产生死锁的四个必要条件之一:
① 破坏“互斥条件”:可以通过采用假脱机(SPOOLing)技术,允许若干个进程同时输出;
② 破坏“不可剥夺”条件:如果资源没有被等待进程占有,那么该进程必须等待,在其等待过程中,其资源也有可能被剥夺;
③ 破坏“请求和保持”条件:可以采用静态分配资源策略,将满足进程条件的资源一次性分配给进程,也可以采用动态资源分配,即需要资源时才提出申请,系统在进行分配;
④ 破坏“循环等待”条件:进程申请资源时,必须严格按照资源编号的顺序进行,否则系统不予分配。
6. 死锁避免
死锁避免的基本思想是:系统对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源; 如果分配后系统可能发生死锁, 则不予分配, 否则予以分配。
这是一种保证系统不进入死锁状态的动态策略。
7. 安全与不安全状态
如果操作系统能保证所有的进程在有限时间内得到所需的全部资源,则称系统处于“ 安全状态”,否则说系统是不安全的。
安全状态是指: 如果存在一个由系统中所有进程构成的安全序列{P1,…, Pn},则系统处于安全状态。一个进程序列{P1,…,Pn}是安全的,如果对于其中每一个进程 Pi( 1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程 pj(j<i) 当前占有资源量之和。系统处于安全状态则不会发生死锁。
如果不存在任何一个安全序列,则系统处于不安全状态。不安全状态一定导致死锁,但不安全状态不一定是死锁状态。即系统若处于不安全状态则可能发生死锁。
8. 银行家算法
银行家算法是一种最有代表性的避免死锁的算法,又被称为“资源分配拒绝”法。
安全序列计算过程:
① 分别求出各进程所需最大资源数量(a)、已分配资源数(b)、缺少资源数(c)和资源剩余可分配量(d);
② 拿 c 和 d 进行比较:
d>c:满足分配,此时 d1=d-c;
否则不满足,寻找下个可满足的进程;
③ 进程分配运行后释放该进程资源,则d2=d1+a=d+b;
④ 按此步骤继续计算寻找可分配进程,直至完成所有进程分配。
9. 死锁解除法
死锁解除法可归纳为两大类:
剥夺资源:使用挂起/激活机制挂起一些进程,剥夺它们占有的资源给死锁进程,以解除死锁。经常使用的方法有还原算法和建立检查点。
撤销进程:撤销死锁进程,将它们占有的资源分配给另一些死锁进程,直到死锁解除为止。撤销代价的标准有进程优先数、进程类的外部代价和运行代价,即重新启动进程并运行到当前撤销点所需要的代价。
10. 资源分配图化简方法
1) 在资源分配图中,找出一个既非等待又非孤立的进程结点 Pi,由于 Pi 可获得它所需要的全部资源,且运行完后释放它所占有的全部资源,故可在资源分配图中消去所有的申请边和分配边,使之成为既无申请边又无分配边的孤立结点。
2) 将 Pi 所释放的资源分配给申请它们的进程,即在资源分配图中将这些进程对资源的申请边改为分配边。
3) 重复 1)、2) 两步骤,直到找不到符合条件的进程结点。
经过化简后,若能消去资源分配图中的所有边,使所有进程都成为孤立结点,则该图是可完全化简的;否则为不可化简的。
所有的化简顺序将导致相同的不可化简图。可以证明,系统处于死锁状态的充分条件是,当且仅当该系统的资源分配图是不可完全化简的。
11. 独占设备预防死锁
对于系统中的独占设备,为预防出现死锁,一般需要避免动态分配锁。也就说,锁应该采用静态分配。
死锁预防的一种措施,就是定时重试和定时放弃锁。
为了避免多个进程同时获取锁,因此锁的分配必须是采用加锁的互斥方式。
死锁预防,在系统设计时确定资源分配算法,保证不发生死锁。
具体的做法是破坏产生死锁的 4 个必要条件之一,其中破坏“循环等待”条件主要是通过“资源有序分配法”来解决死锁。
上一篇
第七章 I/O 设备管理
下一篇