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

一、什么是死锁?

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

二、死锁产生条件

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

环路等待条件。

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. 重复以上两步,直到所有进程都标记为终止,则状态时安全的。 如果一个状态不是安全的,需要拒绝进入这个状态。
相关推荐
周三有雨4 小时前
【面试题系列Vue07】Vuex是什么?使用Vuex的好处有哪些?
前端·vue.js·面试·typescript
爱米的前端小笔记4 小时前
前端八股自学笔记分享—页面布局(二)
前端·笔记·学习·面试·求职招聘
好学近乎知o4 小时前
解决sql字符串
面试
不爱学习的YY酱8 小时前
【操作系统不挂科】<CPU调度(13)>选择题(带答案与解析)
java·linux·前端·算法·操作系统
我明天再来学Web渗透9 小时前
【SQL50】day 2
开发语言·数据结构·leetcode·面试
程序员奇奥10 小时前
京东面试题目分享
面试·职场和发展
理想不理想v11 小时前
【经典】webpack和vite的区别?
java·前端·javascript·vue.js·面试
沈小农学编程13 小时前
【LeetCode面试150】——202快乐数
c++·python·算法·leetcode·面试·职场和发展
钰爱&14 小时前
【操作系统】Linux之网络编程(UDP)(头歌作业)
linux·操作系统
清酒伴风(面试准备中......)14 小时前
操作系统基础——针对实习面试
笔记·面试·职场和发展·操作系统·实习