1、必要条件
- 互斥:每个资源要么已经分配给了一个进程,要么就是可用的。
- 占有和等待:已经得到了某个资源的进程可以再次请求新的资源。
- 不可抢占:已经分配给一个进程的资源不能强制性地被抢占,它只能被占有它的进程显示地释放。
- 环路等待:有两个或者两个以上的进程组成一条环路,该环路中的每个进程都在等待下一个进程所占有的资源。
2、处理方法
主要有一下四种方法:
- 鸵鸟策略
- 死锁检测与死锁恢复
- 死锁预防
- 死锁避免
3、鸵鸟策略
把头埋在沙子里,假装没有发生问题,因为解决死锁问题的代价很高,因此鸵鸟策略这种不采取任务措施的方法会有更高的性能。当发生死锁时,不会对用户造成多大影响,或发生死锁的概率很低,可以采用鸵鸟策略。大多数操作系统,包括Unix,Linux和Windows,处理死锁问题的办法仅仅是忽略它。
4、死锁检测与死锁回复
不视图阻止死锁,二十当检测到死锁发生时,采取措施进行恢复。
4.1、每种类型一个资源的死锁检测
上图为资源分配图,其中方框表示资源,圆圈表示进程。资源指向进程表示该资源已经分配给该进程,进程指向资源表示进程请求获取该资源。
- 图a可以抽取出环,如图b,它满足了环路等待条件,因此会发生死锁。
- 每种类型一个资源的死锁检测算法是通过检测
有向图是否存在环来实现的,从一个节点出发进行深度优先搜索,对方问过的节点进行标记,如果访问了已经标记的节点,就表示有向图存在环,也就是检测到死锁的发生
4.2、每种类型多个资源的死锁检测
上图中,有三个进程四个资源,每个数据代表的含义如下:
- E向量:资源总量
- A向量:资源剩余量
- C矩阵:每个进程所拥有的资源数量,每一行都代表一个进程拥有资源的数量
- R矩阵:每个进程请求的资源数量
进程p1和p2锁请求的资源都得不到满足于,只有进程p3可以,让p3执行,之后释放p3拥有的资源,此时A=(2,2,2,0)。p2可以执行,执行后释放p2拥有的资源,A=(4,2,2,1),p1也可以执行。所有进程都可以顺利执行,没有死锁
算法总结如下:
- 每个进程最开始时都不被标记,执行过程中有可能被标记。当算法结束时,任何没有被标记的进程都是死锁过程。
- 寻找一个没有标记的进程pi,它所请求的资源小于等于A。
- 如果找到了这样一个进程,那么将C矩阵的第i行向量加到A中,标记该进程,并转回1。
- 如果没有这样一样进程,算法终止。
5、死锁预防
在程序运行之前预防死锁发生
5.1、破坏互斥条件
- 例如假脱机打印机技术条件允许若干个进程同时输出,唯一真正请求物理打印机的过程时打印机守护进程。
5.2、破坏占有和等待条件
- 一种实现方式是规定所有进程在开始执行前请求所需要的全部资源。
5.3、破坏不可抢占条件
5.4、破坏环路等待
- 给资源统一编号,进程只能按编号顺序来请求资源
6、死锁避免
在程序运行时避免发生死锁
6.1、安全状态
图a的第二列Has表示已拥有的资源数,第三列Max吧hi傲视总共需要的资源数,Free表示还有可以使用的资源数。从图a开始出发,先让B拥有所需的所有资源(图b),运行结束后释放B,此时Free变为5(图c),接着已同样的方式运行C和A,使得所有进程都能成功运行,因此可以称图a所示的状态是安全的。
-
定义:如果没有死锁发生,并且即使所有进程突然请求对资源的最大需求,也仍然存在某种调度次序能够使得每一次进程运行完毕,则称该状态时安全的。
-
安全状态的检测与死锁的检测类似,因为安全状态必须要求不能发生死锁。下面的银行家算法与死锁检测算法非常类似,可以结合着做参考对比。
6.2、单个资源的银行家算法
一个小城镇的银行家,他想一群客户分别承诺了一定的贷款额度,算法要做的时判断对请求的满足是否会进入不安全状态,如果是,就拒绝请求;否则予以分配。
上图c为不安全状态,因此算法会拒绝之前的请求,避免进入图c中的状态。
6.3、多个资源的银行家算法
上图中有五个进程,四个资源。左边的图表示已经分配的资源,右边的图表示还需要分配的资源。最右边的E、P以及A分别表示:总资源、已分配资源、以及可用资源,注意这三个为向量,而不是具体数值,例如A = (1020),表示4个资源分别还剩下1,0,2,0
- 检查一个状态是否安全的算法如下:
- 查找右边的矩阵是否存在一行小于等于向量A。如果不存在这样的行,那么系统将会发生死锁,状态时不安全的。
- 假若找到这样一行,将该进程标记为终止,并将其已分配资源加到A中。
- 重复以上两步,知道所有进程都标记为终止,则状态时安全的。
- 如果一个状态不是安全的,需要拒绝进入这个状态。