死锁
目录
1 死锁概念
2 死锁的特征
3 死锁的处理方法
4 死锁预防
5 死锁避免
6 死锁检测
7 死锁恢复
8 小结
1 死锁概念
在多道程序设计中,多个进程可以竞争有限数量的资源。如果所申请的资源被其他等待进程占有,那么该等待进程有可能再也无法改变状态。这种情况叫做死锁。
死锁最好的例证就是一项法律:“当两辆列车在十字路口逼近时,他们应该完全停下来,并且一列列车开走之前另一列列车不能再次启动。”
进程在使用资源之前应该申请资源,在使用资源之后应该释放资源。
一个进程可能要申请许多资源,以便完成任务。
使用资源的顺序:
- 1 申请:进程请求资源。如果申请不能立即被允许,那么申请进程应等待,直到它能获得资源为止。
- 2 使用:进程对资源进行操作。
- 3 释放:进程释放资源。
2 死锁的特征
死锁产生的必要条件(4个)
- 互斥:至少有一个资源处于非共享模式,即一次只有一个进程可以使用。如果另一个进程申请该资源,那么申请进程应等到该资源释放为止。
- 占有并等待:一个进程应至少占有一个资源,并等待另一个资源,而该资源为其他进程所占有。
- 非抢占:资源不能被抢占,即资源只有被进程完成任务后自愿释放。
- 循环等待:等待形成一个环。
资源分配图
一种有向图,可以表示资源的分配情况。
图中有两种节点和边。
节点包括:进程节点和资源节点。从进程指向资源的边时申请边。从资源指向进程的边时分配边。
根据资源分配图的定义:如果分配图没有环,那么系统就没有进程死锁。如果有环,那么可能(注意:不是一定)存在死锁。
3 死锁的处理方法
一般来说,处理死锁问题有3种方法。
- 通过协议来预防和避免死锁,确保系统不会进入死锁状态。
- 允许系统进入死锁状态,然后检测它,并加以恢复。
- 忽视这个问题,认为死锁不可能在系统内发生(需要应用程序开发人员自己编写程序处理死锁)
接下来的4~7节就是对处理方法的展开。
4 死锁预防
确保死锁发生的4个必要条件,至少有一个不成立,就能预防死锁发生。
下面就从死锁发生的 4 个必要条件出发,讨论让每一个必要条件不成立的方法。
(1)互斥
互斥是必须成立的。不能让所有的资源都变为共享的,这是不可行的,所有互斥是必须成立的,没有办法从这个必要条件下手。
(2)持有并等待
不让进程持有并等待,那方法就是:当每个进程申请一个资源时,它不能占有其他资源。
有两种协议可以实现:
a. 每个进程在执行前申请并获得所有资源。
b.允许进程在没有资源时才可以申请资源(用几个资源,用完立马释放这些资源,然后再申请其他资源)
缺点:资源利用率低。可能发生饥饿。
(3)无抢占
那就让它可抢占。
如果有一个进程申请一些资源,那么首先检查它们是否可用,如果可用,那就分配它们。
如果不可用,那就检查这些资源是否已分配给等待额外资源的其它进程。如果是,那就抢占这些资源。否则就是这些资源不可用也不被其它等待进程所持有,那就等待。
缺点:不适用于 互斥锁、信号量 等资源。
(4)循环等待
别产生循环等待的情况。
对所有资源类型进行完全排序,要求每个进程按照递增顺序来申请资源。
每个进程只能按递增顺序申请资源。
5 死锁避免
避免死锁同样是属于事先预防的策略,但并不是事先釆取某种限制措施破坏死锁的必要条件,而是在资源动态分配过程中,防止系统进入不安全状态,以避免发生死锁。这种方法所施加的限制条件较弱,可以获得较好的系统性能。
1)安全状态
避免死锁的方法中,允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次资源分配的安全性。若此次分配不会导致系统进入不安全状态,则将资源分配给进程; 否则,让进程等待。
所谓安全状态,是指系统能按某种进程推进顺序( P1, P2, …, Pn),为每个进程Pi分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都可顺序地完成。此时称 P1, P2, …, Pn 为安全序列。如果系统无法找到一个安全序列,则称系统处于不安全状态。
并非所有的不安全状态都是死锁状态,但当系统进入不安全状态后,便可能进入死锁状态;反之,只要系统处于安全状态,系统便可以避免进入死锁状态。
2)资源分配图算法
在资源分配图中添加一种边,为需求边,表示进程将来在某个时候申请资源。
检测算法就检测分配图会不会形成一个环,如果会,那就是非安全算法。就不会分配资源。
例如下图,R2资源是空闲的、可用的,假设P2 申请资源 R2,系统不给它分配,因为这样就形成一个环,进入非安全状态。
缺点:只适用于每种资源类型只有一个实例。
3)银行家算法
银行家算法是最著名的死锁避免算法。它提出的思想是:把操作系统看做是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。
6 死锁检测
如果一个系统既不采用死锁预防算法也不采用死锁避免算法,那么死锁就可能出现。
系统可以提供
- 一个用来检查系统状态从而确定是否出现死锁的算法。
- 一个用来从死锁中恢复的算法。
1)每种资源类型只有单个实例
化简资源分配图为等待图来检查是否发生了死锁。
当且仅当等待图中有一个环,系统死锁。
2)每种资源类型有多个实例
………………
7 死锁恢复
一旦检测出死锁,就应立即釆取相应的措施,以解除死锁。死锁解除的主要方法有:
-
资源剥夺法。挂起某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。但应防止被挂起的进程长时间得不到资源,而处于资源匮乏的状态。
-
撤销进程法。强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源。撤销的原则可以按进程优先级和撤销进程代价的高低进行。
-
进程回退法。让一(多)个进程回退到足以回避死锁的地步,进程回退时自愿释放资源而不是被剥夺。要求系统保持进程的历史信息,设置还原点。
8 小结
没有单独的基本方法能够处理操作系统资源分配的所有问题。然而通过合并基本方法,使得我们能够为系统中的每一类资源选择最佳方法。