进程死锁的危害、导致原因、解决方法
在多个程序同时执行的情况下,多个进程可能出现竞争一定数量的资源。若某个进程申请资源,且此时资源不可用,那么该进行将进入等待状态。如果所申请的资源被其他等待进程占有,那么该等待进程有可能永远处于等待状态而无法改变该状态。——这种情况即为死锁。
或许你认为进程死锁就死锁呗,那又能怎么样?那么先说出它的危害吧!
当出现死锁时,进程永远不能完成,并且阻碍使用系统资源,阻止了其他作业开始执行,导致系统的资源利用率急剧下载,下面列举出一些比较直接的影响。
(1)死锁会使进程得不到正确的结果。因为处于死锁状态的进程得不到所需的资源,不能向前推进,故得不到结果。
(2)死锁会使资源的利用率降低。因为处于死锁状态的进程不释放已占有的资源,以至于这些资源不能被其他进程利用,故系统资源利用率降低。
(3)死锁还会导致产生新的死锁。其它进程因请求不到死锁进程已占用的资源而无法向前推进,所以也会发生死锁。
所以进程出现了死锁,有可能产生多米诺骨牌效应,最终会导致操作系统崩溃。
进程死锁有这么厉害的副作用,那么在什么条件下产生死锁呢?
进程死锁的四个必要条件:
(1) 互斥:至少有一个资源必须处于非共享模式,即一个资源一次只有一个进程使用。如果另一进程申请该资源,那么申请进程必须等到该资源被释放为止。
(2) 占有并等待:一个进程必须占有至少一个资源,并等待另一为其他进程所占有的资源。
(3) 非抢占:资源不能被抢占,即资源只能在进程完成任务后自动释放。
(4) 循环等待: 有一组等待进程{P0, P1, ..., Pn},P0等待的资源为P1所占有,P1等待的资源为P2所占有,。。。,Pn-1等待的资源为Pn所占有,最后Pn等待的资源为P0所占有,从而形成了一个等待循环。
如果出现了同时满足上述四个条件的多个进程,那么就会出现进程死锁。如何解决死锁的问题呢?
针对死锁出现之后的解决方法需要从原理上来说解决,这也是绝大多数操作系统所采用的方法:
(1) 使用协议以预防或避免死锁,确保系统不会进入死锁状态;
(2) 系统可进入死锁状态,但可检测死锁状态,然后进行恢复;
(3) 忽视该问题,而认为死锁不可能在系统内发生。 ——即应用程序开发人员来处理死锁问题
其中第一种方法为死锁预防、避免。
既然需要同时满足四个条件还能出现死锁,那么预防死锁的方法显然会有多种。预防的核心思想即为,打破同时满足四个条件的条件,即可解决进程死锁的问题。也就是说,只要确保至少有一个必要条件不成立,就能预防死锁发生。
互斥——对于非共享资源,必须要有互斥条件。不过通常不能通过否定互斥条件来预防死锁:有的资源本身就是非共享的。
占有并等待——打破该条件,必须保证:当一个进程申请一个资源时,它不能占有其他资源。
非抢占——对已分配的资源不能抢占。确保该条件不成立,可以使用如下协议:如果一个进程占有资源并申请并一个不能立即分配的资源,那么其现已分配的资源都可被抢占。即这些资源都被隐式释放。
循环等待——确保该条件不成立的方法是对所有资源类型进行完全排序,且要求每个进程按递增顺序来申请资源。
预防死锁的副作用是降低设备的使用率和系统的吞吐率。
而对于死锁避免,要求操作系统事先得到有关进程申请资源和使用资源的额外信息。通过获悉这 些信息,系统将能够确定:对于一个申请,进程是否应等待。死锁避免算法动态地检测资源分配状态以确保循环等待条件不可能成立。资源分配状态是由可用资源和 已分配资源,及进程最大需求所决定的。对于死锁避免算法,不得不提到的概念——安全状态。如果系统能按某个顺序为每个进程分配资源(不超过其最大值)并能 避免死锁,那么系统状态就是安全的。死锁避免算法一般有两种:
(1)资源分配图算法——针对每种资源类型只有单个实例的资源分配系统;
(2)银行家算法——适用于每种资源类型有多个实例的资源分配系统,但效率比资源分配图方案低。
当死锁避免和死锁预防都失效后,那么就可以使用方法2了!在这种环境下,系统需要提供两种算法:
(1)检测系统状态,并能够确定是否出现了死锁;
(2)出现死锁时,及时恢复
检测死锁的算法需要区分每种资源类型只有单个实例和多个实例的情况:
当只有单个实例时,可以使用资源分配图的一个变种,即等待图。从资源分配图种,删除所有的资源类型节点,合并适当边,即可得到等待图。
当有多个实例时,需要采用银行家算法的变种,而使用了一些随时间而变化的数据结构
为了提高检测算法的效率,需要确定何时调用检测算法。这取决于两种因素:
(1)死锁发生的频率;——如果经常发生死锁,那么就应经常调用检测算法。而当某个进程提出请求且得不到满足时,有可能出现死锁。在极端情况下,每次请求分配不摁嗯立即得到允许时,就调用死锁检测算法。
(2)死锁发生了,影响的进程数量有多少
当检测到死锁确实存在时,那么需要采用多种措施进行死锁恢复。一般来说,有两种措施:1.通知操作员死锁发生,而让操作人员人工处理死锁;2.让系统从死锁状态中自动恢复过来。打破死锁的两种是:1.简单地终止一个或多个进程以打破循环等待;2.从一个或多个死锁进程那里抢占一个或多个资源。
进程终止方法:1.一次只终止一个进程直到取消死锁循环为止。每次终止一个进程,都必须调用死锁检测算法以确定进程是否仍处于死锁;每次终止地进程需要一定地策略来确定终止代价最小地进程。
2.终止所有进程。终止了死锁循环,但其进程地计算结果必须放弃,代价较大。
使用抢占来处理死锁,需要三个问题需要处理:
1.如何选择一个牺牲品;
2.回滚:对于被抢占资源的资源,需要对该进程做什么安排;
3.饥饿:如何保证资源不会总是从同一个进程中被抢占。
进程死锁可以说一个资源分配的问题,如何解决其实可以认为是一个哲学问题。需要将上面的方法组合起来,以及针对系统的特征,才能最佳地处理系统地各种类型资源地分配问题。