操作系统之进程死锁

什么是死锁?


       举个例子:在一条河上有一座桥,桥面较窄,只能容纳一辆汽车通过,无法让两辆汽车并行。如果有两辆汽车A和B分别由桥的两端驶上该桥,则对于A车来说,它走过桥面左面的一段路(即占有了桥的一部分资源),要想过桥还须等待B车让出右边的桥面,此时A车不能前进;对于B车来说,它走过桥面右边的一段路(即占有了桥的一部分资源),要想过桥还须等待A车让出左边的桥面,此时B车也不能前进。两边的车都不倒车,结果造成互相等待对方让出桥面,但是谁也不让路,就会无休止地等下去。这种现象就是死锁。如果把汽车比做进程,桥面作为资源,那麽上述问题就描述为:进程A占有资源R1,等待进程B占有的资源Rr;进程B占有资源Rr,等待进程A占有的资源R1。而且资源R1和Rr只允许一个进程占用,即:不允许两个进程同时占用。结果,两个进程都不能继续执行,若不采取其它措施,这种循环等待状况会无限期持续下去,就发生了进程死锁。 

       进程死锁:两个或两个以上的进程在执行过程中,因为争夺资源而造成的一种相互等待的现象,若无外力作用,他们都将无法推进下去,此时系统产生死锁。

死锁必要条件


产生进程死锁的4个必要条件:

     互斥条件:资源不能被共享,每个资源一次只能被一个进程使用;

     请求与保持条件:指进程已经保持了至少一个资源,又提出新的资源请求,而该资源又被其他进程占有,此时请求进程阻塞,但又对自己获得的资源保持不放。

     不剥夺条件:进程已获得资源,在未使用完之前,不能强行剥夺;

     循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

  上面我们提到的这四个条件在死锁时会同时发生。也就是说,只要有一个必要条件不满足,则死锁就可以排除。

死锁处理办法


针对死锁出现之后的解决方法需要从原理上来说解决,这也是绝大多数操作系统所采用的方法:

(1)  使用协议以预防或避免死锁,确保系统不会进入死锁状态;

(2)  系统可进入死锁状态,但可检测死锁状态,然后进行解决;

预防死锁

      既然需要同时满足四个条件还能出现死锁,那么预防死锁的方法显然会有多种。预防的核心思想即为,打破同时满足四个条件的条件,即可解决进程死锁的问题。也就是说,只要确保至少有一个必要条件不成立,就能预防死锁发生。

          互斥——对于非共享资源,必须要有互斥条件。不过通常不能通过否定互斥条件来预防死锁:有的资源本身就是非共享的。

          占有并等待——打破该条件,必须保证:当一个进程申请一个资源时,它不能占有其他资源

          非抢占——对已分配的资源不能抢占。确保该条件不成立,即一个已占有资源的进程若要再申请新的资源,它必须先释放已占有的资源。若随后再需要这些资源,需要重新申请。

          循环等待——确保该条件不成立的方法是对所有资源类型进行完全排序,且要求每个进程按递增顺序来申请资源

          预防死锁的副作用降低设备的使用率和系统的吞吐率

避免死锁

      要求操作系统事先得到有关进程申请资源和使用资源的额外信息。通过获悉这 些信息,系统将能够确定:对于一个申请,进程是否应等待。死锁避免算法动态地检测资源分配状态以确保循环等待条件不可能成立。资源分配状态是由可用资源和 已分配资源,及进程最大需求所决定的。对于死锁避免算法,不得不提到的概念——安全状态。如果系统能按某个顺序为每个进程分配资源(不超过其最大值)并能 避免死锁,那么系统状态就是安全的。死锁避免算法一般有两种:

  1. 资源分配图算法——针对每种资源类型只有单个实例的资源分配系统;
  2. 银行家算法——适用于每种资源类型有多个实例的资源分配系统,但效率比资源分配图方案低。

检测死锁

    当死锁避免和死锁预防都失效后,那么就必须要检测出进程是否死锁还是进程异常,系统需要提供两种算法:

  1. 检测系统状态,并能够确定是否出现了死锁;
  2. 出现死锁时,及时解决

         检测死锁的算法需要区分每种资源类型只有单个实例和多个实例的情况:

         当只有单个实例时,可以使用资源分配图的一个变种,即等待图。从资源分配图种,删除所有的资源类型节点,合并适当边,即可得到等待图。

         当有多个实例时,需要采用银行家算法的变种,而使用了一些随时间而变化的数据结构

          为了提高检测算法的效率,需要确定何时调用检测算法。这取决于两种因素:

  1. 死锁发生的频率;——如果经常发生死锁,那么就应经常调用检测算法。而当某个进程提出请求且得不到满足时,有可能出现死锁。在极端情况下,每次请求分配不摁嗯立即得到允许时,就调用死锁检测算法。
  2. 死锁发生了,影响的进程数量有多少

死锁解除

    常见的解除死锁的两种方法:

  1. 剥夺资源,从其他进程剥夺足够数量的资源给死锁进程,以解除死锁状态。
  2. 撤销进程,最简单的撤销进程方法是使全部死锁进程都夭折掉,稍微温和点的方法是按照某种顺序逐个的撤销进程,直至有足够的资源可用,使死锁进程状态取消。

参考

http://www.cnblogs.com/bao-yu/p/5429300.html

http://blog.csdn.net/jirongzi_cs2011/article/details/9406281

原文地址:https://www.cnblogs.com/sasuke-y/p/5666075.html