【面试八股总结】死锁:产生条件、预防死锁、处理死锁、避免死锁

一、什么是死锁?

死锁是指两个(或多个)线程互相等待对方数据的过程,死锁的产生导致程序卡死,不解锁程序将永远⽆法进⾏下 去

二、死锁产生条件

死锁只有同时满足以下四个条件才会发生:互斥条件;持有并等待条件;不可剥夺条件;

环路等待条件。

1. 互斥条件

进程对所需求的资源具有排他性,若有其他进程请求该资源,请求进程只能等待。

2. 持有并等待条件

进程当前所拥有的资源在进程请求其他新资源时,由该进程继续占有。

3. 不可剥夺条件

进程在所获得的资源未释放前,不能被其他进程强行夺走,只能自己释放。

  • 可抢占资源:可以从拥有它的进程中抢占而不会产⽣任何副作用,存储器就是⼀类可抢占资源。
  • 不可抢占资源:指在不引起相关计算失败的情况下,无法把它从占有它的进程处抢占过来。

4. 环路等待条件

存在⼀种进程资源循环等待链,链中每个进程已获得的资源同时被链中下⼀个进程所请求。

三、如何预防死锁?

1. 破坏互斥条件

例如假脱机打印机技术允许若干个进程同时输出,唯⼀真正请求物理打印机的进程是打印机守护进程。

2. 破坏请求和保持条件

⼀种实现方式是规定所有进程在开始执行前请求所需要的全部资源。

3. 破坏不剥夺条件

允许抢占资源

4. 破坏循环请求等待

给资源统⼀编号,进程只能按编号顺序来请求资源。

四、发现死锁如何处理?

1. 鸵鸟策略

把头埋在沙子里,假装根本没发生问题。 因为解决死锁问题的代价很高,因此鸵鸟算法这种不采取任务措施的方案会获得更高的性能。当发生死锁时不会对用户造成很大影响,或发生死锁的概率很低,可以采用鸵鸟算法。大多数操作系统,包括 Unix,Linux 和 Windows,处理死锁问题的办法仅仅是忽略它。

**2.**死锁检测与死锁恢复

不试图阻止死锁,而是当检测到死锁发生时,采取措施进行恢复。

(1)每种类型⼀个资源的死锁检测

通过检测有向图中是否存在环来实现,从⼀个节点出发进行深度优先搜索,对访问过的节点进行标记,如果访问了已经标记的节点,就表示有向图存在环,也就是检测到死锁发生。

(2)每种类型多个资源的死锁检测

每个进程最开始时都不被标记,执行过程有可能被标记。当算法结束时**,任何没有被标记的进程都是死锁进程。**

  1. 寻找⼀个没有标记的进程Pi,它所请求的资源小于或等于 A ;
  2. 如果真找到这样⼀个进程,那么将C矩阵的第 i 行向量加到 A 中,标记该进程,并转回第1步;
  3. 如果没有这样的进程,那么算法终止。

举个🌰:

上图中,有三个进程四个资源,每个数据代表的含义如下:

  • E 向量:资源总量
  • A 向量:资源剩余量
  • C矩阵:每个进程所拥有的资源数量,每一行都代表一个进程拥有资源的数量
  • R 矩阵:每个进程请求的资源数量

进程 P1 和 P2 所请求的资源都得不到满足,只有进程 P3 可以,让 P3 执⾏,之后释放 P3 拥有的资源,此时 A = (2 2 2 0)。P2 可以执⾏,执⾏后释放 P2 拥有的资源,A = (4 2 2 1) 。P1 也可以执⾏。所有进程都可以顺利执⾏,没有死锁。

检测到死锁之后,可以采用以下方法进行恢复:

  • 利用抢占恢复 将进程挂起,强⾏取走资源给另⼀个进程使用,用完再放回
  • 利用回滚恢复 复位到更早的状态,那时它还没有取得所需的资源
  • 通过杀死进程恢复 杀掉环中的⼀个进程或多个,牺牲掉⼀个环外进程

五、程序运行中如何避免死锁?

**安全状态:**如果没有死锁发生,并且即使所有进程突然请求对资源的最大需求,也仍然存在某种调度次序能够使得每⼀个进程运行完毕,则称该状态是安全的。

Has 表示已拥有的资源数,Max 表示总共需要的资源数,Free 表示还有可以使⽤的资源数。

从图 a 开始出发,先让 B 拥有所需的所有资源(图 b),运行结束后释放 B,此时 Free 变为 5(图 c);接着以同样的方式运行 C 和 A,使得所有进程都能成功运行,因此可以称图 a 所示的状态时安全的。

++安全状态的检测与死锁的检测类似,因为安全状态必须要求不能发生死锁。下面的银行家算法与死锁检测算法非常类似,可以结合着做参考对对比。++

(1)单个资源的银行家算法

一个小城镇的银行家,他向⼀群客户分别承诺了一定的贷款额度,算法要做的是判断对请求的满足是否会进入不安全状态,如果是,就拒绝请求;否则予以分配。

(2)多个资源的银行家算法

  1. 查找是否存在所需资源矩阵(Max-Has)小于等于资源剩余量A的进程。如果不存在这样的行,那么系统将会发生死锁,状态是不安全的。
  2. 假若找到这样的进程,将该进程标记为终止,并将其已分配资源加到 A 中。
  3. 重复以上两步,直到所有进程都标记为终止,则状态时安全的。 如果一个状态不是安全的,需要拒绝进入这个状态。
相关推荐
LCG元30 分钟前
【面试问题】JIT 是什么?和 JVM 什么关系?
面试·职场和发展
GISer_Jing5 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试
m0_748245525 小时前
吉利前端、AI面试
前端·面试·职场和发展
TodoCoder6 小时前
【编程思想】CopyOnWrite是如何解决高并发场景中的读写瓶颈?
java·后端·面试
Wyang_XXX7 小时前
CSS 选择器和优先级权重计算这么简单,你还没掌握?一篇文章让你轻松通关面试!(下)
面试
liyinuo201710 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范
代码中の快捷键11 小时前
java开发面试有2年经验
java·开发语言·面试
p@nd@13 小时前
Oracle筑基篇-调度算法-LRU的引入
数据库·oracle·操作系统·lru
bufanjun00114 小时前
JUC并发工具---ThreadLocal
java·jvm·面试·并发·并发基础
Zhu_S W1 天前
Java web的发展历史
面试·职场和发展