死锁
1.为什么会出现死锁?
因为并发的进程分别拥有一部分资源,而又想抢占其他进程的资源。(如果只有一个进程,绝对不会出现死锁)
//资源包括:CPU,I/O通道,各类存储,设备和数据,文件,数据库,信号量(且要求资源不会突然死掉)
2.死锁模型
P代表进程 R代表资源,R里面的点的个数代表资源的个数
不会发生死锁,因为P3使用完R3之后一定会释放
会出现死锁。
不会出现死锁(虽然有环)
3.死锁的特征(只是死锁的必要条件)
(1)互斥:资源同一时间只能被一个进程拥有,如果可以同时拥有,也不会出现死锁
(2)持有并等待:进程保持至少一个资源,并且在等待获取其他进程持有的额外资源
(3)无抢占:一个资源只能被进程完成任务后自动释放
(4)循环等待:就是几个进程互相等待
4.死锁的处理办法
(1)死锁预防:只有打破死锁的一个必要条件,就不会出现死锁
打破互斥:使资源可以同时被进程占用(不太好)
打破持有并等待:不持有一部分资源。我要么不拿,要么就拿到全部的资源(这样会使得系统的利用率很低,使某些进程饥饿,也不好)
打破无抢占:可以抢占(想抢占的话只能kill一部分资源,太暴力)
打破循环等待:对所有资源进行排序,并要求每个进程按照资源的顺序进行申请。(适用于资源比较有限的系统,比如嵌入式系统)
比如说有进程A,B和资源1,2。并且这两个进程都需要这两个资源。
只有先申请到了1才能去申请2,这样就不会出现一个占有1,一个占有2的情况。
(2)死锁避免:某进程申请资源时判断是否会出现不安全状态,如果会出现,就不将该资源分配给此进程
不安全状态包括死锁状态
安全状态的定义:针对所有进程,存在安全序列(所以需要寻找安全序列)
序列<p1,p2...pn>是安全的:顺序执行这些进程,如果每个进程都能顺利执行,该序列就是安全序列
1)对于每个pi,pi要求的资源能够由当前可用资源+所有的pj持有的资源来满足(j<i)
2)pi完成之后,pi+1可以得到所需资源,执行完后返回资源
比如这张图,p1,p2都需要R1,R2 ,并且p1获得了R1
(1)P1申请R2时,若将R2分配给P1
序列<p1,p2>是安全的,序列<p2,p1>是不安全的
存在安全序列,申请成功
(2)P2申请R2时,若将R2分配给P2
序列<p1,p2>和序列<p2,p1>都是不安全的,
不存在安全序列,申请失败
(3)死锁避免的经典算法--银行家算法 假设A,B,C的资源总数分别为 10,5,7
表为T0时刻的资源状态图
进程\资源状况 |
max A B C |
Allocation(分配) A B C |
Avaliable(可利用) A B C |
P0 | 7 5 3 | 0 1 0 | 3 3 2 |
P1 | 3 2 2 | 2 0 0 | |
P2 | 9 0 2 | 3 0 2 | |
P3 | 2 2 2 | 2 1 1 | |
P4 | 4 3 3 | 0 0 2 |
max表示的是各个进程在整个执行阶段所需要的各类资源
Allocation表示的是当前时刻已经给各个进程分配的资源
max-Allocation 得到的就是各个进程剩余时间内还需要的进程矩阵
减去 =
max Allocation Need
将Avaliable 与Need矩阵进行比较,发现p1和p3安全,也就是操作系统当前拥有的资源可以供p1或p3进程完成他所以的操作
我们选择p1完成,p1加入安全队列
Avaliable 更新为 (3 3 2) + (2 0 0) = (5,3,2)
按照同样的方法得到安全序列<p1,p3,p4,p2,p0> 当然这里的安全序列不止一个
(4)死锁检测与恢复
允许程序进入死锁,如果检测到了死锁,就启动恢复机制解除死锁
把资源分配图简化为等待图:
等待图如果有环,表明可能死锁了
死锁解除的方法:
(1)资源剥夺法:挂起某些死锁进程,并抢占它的资源,将该资源分配给其他的死锁进程。
但应防止被挂起的进程长时间得不到资源
(2)撤销进程法:强制撤销部分甚至全部死锁进程并剥夺这些进程的资源。
撤销的原则按照进程优先级和撤销代价的高低进行
(3)进程回退法:让一(多)个进程回退到足以回避死锁的地步,进程回退时自愿释放
资源而不是被剥夺。要求系统保持进程的历史信息,设置还原点