CS-Notes/docs/notes/计算机操作系统 - 死锁.md

154 lines
8.1 KiB
Java
Raw Normal View History

2019-04-21 10:36:08 +08:00
<!-- GFM-TOC -->
2019-03-27 20:57:37 +08:00
* [必要条件](#必要条件)
* [处理方法](#处理方法)
* [鸵鸟策略](#鸵鸟策略)
* [死锁检测与死锁恢复](#死锁检测与死锁恢复)
* [1. 每种类型一个资源的死锁检测](#1-每种类型一个资源的死锁检测)
* [2. 每种类型多个资源的死锁检测](#2-每种类型多个资源的死锁检测)
* [3. 死锁恢复](#3-死锁恢复)
* [死锁预防](#死锁预防)
* [1. 破坏互斥条件](#1-破坏互斥条件)
* [2. 破坏占有和等待条件](#2-破坏占有和等待条件)
* [3. 破坏不可抢占条件](#3-破坏不可抢占条件)
* [4. 破坏环路等待](#4-破坏环路等待)
* [死锁避免](#死锁避免)
* [1. 安全状态](#1-安全状态)
* [2. 单个资源的银行家算法](#2-单个资源的银行家算法)
* [3. 多个资源的银行家算法](#3-多个资源的银行家算法)
2019-04-21 10:36:08 +08:00
<!-- GFM-TOC -->
2019-03-27 20:57:37 +08:00
# 必要条件
2019-04-25 18:43:33 +08:00
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c037c901-7eae-4e31-a1e4-9d41329e5c3e.png"/> </div><br>
2019-03-27 20:57:37 +08:00
- 互斥每个资源要么已经分配给了一个进程要么就是可用的
- 占有和等待已经得到了某个资源的进程可以再请求新的资源
- 不可抢占已经分配给一个进程的资源不能强制性地被抢占它只能被占有它的进程显式地释放
- 环路等待有两个或者两个以上的进程组成一条环路该环路中的每个进程都在等待下一个进程所占有的资源
# 处理方法
2019-03-09 08:31:29 +08:00
主要有以下四种方法
2019-03-27 20:57:37 +08:00
- 鸵鸟策略
- 死锁检测与死锁恢复
- 死锁预防
- 死锁避免
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
# 鸵鸟策略
2019-03-09 08:31:29 +08:00
把头埋在沙子里假装根本没发生问题
因为解决死锁问题的代价很高因此鸵鸟策略这种不采取任务措施的方案会获得更高的性能
当发生死锁时不会对用户造成多大影响或发生死锁的概率很低可以采用鸵鸟策略
2019-03-27 20:57:37 +08:00
大多数操作系统包括 UnixLinux Windows处理死锁问题的办法仅仅是忽略它
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
# 死锁检测与死锁恢复
2019-03-09 08:31:29 +08:00
不试图阻止死锁而是当检测到死锁发生时采取措施进行恢复
2019-03-27 20:57:37 +08:00
## 1. 每种类型一个资源的死锁检测
2019-03-09 08:31:29 +08:00
2019-04-25 18:43:33 +08:00
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/b1fa0453-a4b0-4eae-a352-48acca8fff74.png"/> </div><br>
2019-03-09 08:31:29 +08:00
上图为资源分配图其中方框表示资源圆圈表示进程资源指向进程表示该资源已经分配给该进程进程指向资源表示进程请求获取该资源
2019-03-27 20:57:37 +08:00
a 可以抽取出环如图 b它满足了环路等待条件因此会发生死锁
2019-03-09 08:31:29 +08:00
每种类型一个资源的死锁检测算法是通过检测有向图是否存在环来实现从一个节点出发进行深度优先搜索对访问过的节点进行标记如果访问了已经标记的节点就表示有向图存在环也就是检测到死锁的发生
2019-03-27 20:57:37 +08:00
## 2. 每种类型多个资源的死锁检测
2019-03-09 08:31:29 +08:00
2019-04-25 18:43:33 +08:00
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/e1eda3d5-5ec8-4708-8e25-1a04c5e11f48.png"/> </div><br>
2019-03-09 08:31:29 +08:00
上图中有三个进程四个资源每个数据代表的含义如下
2019-03-27 20:57:37 +08:00
- E 向量资源总量
- A 向量资源剩余量
- C 矩阵每个进程所拥有的资源数量每一行都代表一个进程拥有资源的数量
- R 矩阵每个进程请求的资源数量
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
进程 P<sub>1</sub> P<sub>2</sub> 所请求的资源都得不到满足只有进程 P<sub>3</sub> 可以 P<sub>3</sub> 执行之后释放 P<sub>3</sub> 拥有的资源此时 A = (2 2 2 0)P<sub>2</sub> 可以执行执行后释放 P<sub>2</sub> 拥有的资源A = (4 2 2 1) P<sub>1</sub> 也可以执行所有进程都可以顺利执行没有死锁
2019-03-09 08:31:29 +08:00
算法总结如下
每个进程最开始时都不被标记执行过程有可能被标记当算法结束时任何没有被标记的进程都是死锁进程
2019-03-27 20:57:37 +08:00
1. 寻找一个没有标记的进程 P<sub>i</sub>它所请求的资源小于等于 A
2. 如果找到了这样一个进程那么将 C 矩阵的第 i 行向量加到 A 标记该进程并转回 1
3. 如果没有这样一个进程算法终止
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
## 3. 死锁恢复
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
- 利用抢占恢复
- 利用回滚恢复
- 通过杀死进程恢复
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
# 死锁预防
2019-03-09 08:31:29 +08:00
在程序运行之前预防发生死锁
2019-03-27 20:57:37 +08:00
## 1. 破坏互斥条件
2019-03-09 08:31:29 +08:00
例如假脱机打印机技术允许若干个进程同时输出唯一真正请求物理打印机的进程是打印机守护进程
2019-03-27 20:57:37 +08:00
## 2. 破坏占有和等待条件
2019-03-09 08:31:29 +08:00
一种实现方式是规定所有进程在开始执行前请求所需要的全部资源
2019-03-27 20:57:37 +08:00
## 3. 破坏不可抢占条件
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
## 4. 破坏环路等待
2019-03-09 08:31:29 +08:00
给资源统一编号进程只能按编号顺序来请求资源
2019-03-27 20:57:37 +08:00
# 死锁避免
2019-03-09 08:31:29 +08:00
在程序运行时避免发生死锁
2019-03-27 20:57:37 +08:00
## 1. 安全状态
2019-03-09 08:31:29 +08:00
2019-04-25 18:43:33 +08:00
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ed523051-608f-4c3f-b343-383e2d194470.png"/> </div><br>
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
a 的第二列 Has 表示已拥有的资源数第三列 Max 表示总共需要的资源数Free 表示还有可以使用的资源数从图 a 开始出发先让 B 拥有所需的所有资源 b运行结束后释放 B此时 Free 变为 5 c接着以同样的方式运行 C A使得所有进程都能成功运行因此可以称图 a 所示的状态时安全的
2019-03-09 08:31:29 +08:00
定义如果没有死锁发生并且即使所有进程突然请求对资源的最大需求也仍然存在某种调度次序能够使得每一个进程运行完毕则称该状态是安全的
安全状态的检测与死锁的检测类似因为安全状态必须要求不能发生死锁下面的银行家算法与死锁检测算法非常类似可以结合着做参考对比
2019-03-27 20:57:37 +08:00
## 2. 单个资源的银行家算法
2019-03-09 08:31:29 +08:00
一个小城镇的银行家他向一群客户分别承诺了一定的贷款额度算法要做的是判断对请求的满足是否会进入不安全状态如果是就拒绝请求否则予以分配
2019-04-25 18:43:33 +08:00
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/d160ec2e-cfe2-4640-bda7-62f53e58b8c0.png"/> </div><br>
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
上图 c 为不安全状态因此算法会拒绝之前的请求从而避免进入图 c 中的状态
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
## 3. 多个资源的银行家算法
2019-03-09 08:31:29 +08:00
2019-04-25 18:43:33 +08:00
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/62e0dd4f-44c3-43ee-bb6e-fedb9e068519.png"/> </div><br>
2019-03-09 08:31:29 +08:00
2019-03-27 20:57:37 +08:00
上图中有五个进程四个资源左边的图表示已经分配的资源右边的图表示还需要分配的资源最右边的 EP 以及 A 分别表示总资源已分配资源以及可用资源注意这三个为向量而不是具体数值例如 A=(1020)表示 4 个资源分别还剩下 1/0/2/0
2019-03-09 08:31:29 +08:00
检查一个状态是否安全的算法如下
2019-03-27 20:57:37 +08:00
- 查找右边的矩阵是否存在一行小于等于向量 A如果不存在这样的行那么系统将会发生死锁状态是不安全的
- 假若找到这样一行将该进程标记为终止并将其已分配资源加到 A
- 重复以上两步直到所有进程都标记为终止则状态时安全的
2019-03-09 08:31:29 +08:00
如果一个状态不是安全的需要拒绝进入这个状态
2019-03-27 20:57:37 +08:00
2019-06-13 13:31:54 +08:00
# 微信公众号
2019-06-10 11:23:18 +08:00
2019-06-18 00:57:23 +08:00
更多精彩内容将发布在微信公众号 CyC2018 你也可以在公众号后台和我交流学习和求职相关的问题另外公众号提供了该项目的 PDF 等离线阅读版本后台回复 "下载" 即可领取公众号也提供了一份技术面试复习大纲不仅系统整理了面试知识点而且标注了各个知识点的重要程度从而帮你理清多而杂的面试知识点后台回复 "大纲" 即可领取我基本是按照这个大纲来进行复习的对我拿到了 BAT 头条等 Offer 起到很大的帮助你们完全可以和我一样根据大纲上列的知识点来进行复习就不用看很多不重要的内容也可以知道哪些内容很重要从而多安排一些复习时间
2019-06-10 11:23:18 +08:00
2019-07-13 23:43:34 +08:00
<br><div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/other/公众号海报.png?v=2"></img></div>