死锁特征
进程在使用资源前必须申请资源,在使用资源之后必须释放资源。(申请,使用,释放)
死锁的必要条件:
- 互斥:至少有一个资源处于非共享模式,如果另一个进程申请该资源,必须等到该资源被释放。
- 占有并等待:一个进程必须占有至少一个资源,并等待另一个被其他进程占有的资源。
- 非抢占:资源不能被抢占,即资源只能在进程完成任务后自动释放。
- 循环等待:有一组等待进程{P0,P1,…,Pn},P0等待的资源被P1占有,P1等待的资源被P2占有,…,Pn等待的资源被P0占有。
四个条件同时满足会引发死锁
资源分配图
![](https://i-blog.csdnimg.cn/blog_migrate/c55869af088645923c7a0f1045ae023d.png)
有向边Pi→Rj称为申请边,有向边Rj→Pi称为分配边
如果每个资源类型只有一个实例,有环就有死锁。
如果分配图没有环,那么系统就没有进程死锁。
进程P1,P2,P3是死锁,进程P2等待资源R3,而R3被进程P3占有。另一方面,进程P3等待进程P1或P2释放资源R2。另外,进程P1等待进程P2释放资源R1。
死锁处理办法
- 使用协议预防或避免死锁,确保系统不会进入死锁状态
- 允许进入死锁,通过检测恢复
- 可以忽视这个问题
死锁预防
确保4个必要条件至少一个不成立
互斥
共享资源不要求互斥访问,不会出现死锁,不过有些资源本身就是非共享的。
占有并等待
当一个进程申请一个资源时,它不能占有其他资源
- 一种协议是每个进程在执行前申请并获得所有资源
- 一种协议是允许进程在没有资源时才能申请资源
这两种协议的缺点:
- 资源利用率比较低,很多已分配的资源可能很长时间没有被使用
- 饥饿,一个需要多个资源的进程会永久等待,其所需的资源分配给了其他进程
非抢占
如果一个进程占有资源并申请另一个不能立即分配的资源,其已分配的资源可被抢占。
循环等待
对所有资源类型进行完全排序,要求每个进程按递增顺序来申请资源。
要求当一个进程申请资源类型Rj时,必须释放所有资源Ri (F(Ri)>=F(Rj))
死锁避免
上面预防死锁的副作用是低设备使用率和系统吞吐率
每次申请要求系统考虑现有可用资源,已分配资源和每个进程将来申请与释放的资源,来决定当前申请是否满足或等待,避免死锁的发生。
例如死锁避免算法动态的检测资源分配状态以确保循环等待的条件不可能成立。
安全状态
进程序列{P1,P2,…,Pn},如果对于每个Pi,Pi可以申请的资源数小于当前可用资源加上所有进程Pj (j<i)所占有的资源,那么这一顺序称为安全序列。
如果存在一个安全序列,那么系统处于安全状态。
死锁状态时不安全状态。
资源分配图算法
假设进程Pi申请资源Rj,只有在将申请边Pi→Rj变成分配边Rj→Pi而不导致资源分配图形成环,才允许分配。通过环检测算法,检测安全性。
银行家算法
当进程进入系统,它必须说明可能需要的每种类型资源实例的最大数量,这一数量不能超过系统资源总和。当用户申请一组资源时,系统必须确定这些资源的分配是否仍会时系统处于安全状态。如果是,就分配资源;否则,进程等待直到某个其他进程释放足够资源。
Available:表示每种资源现有实例的数量
Max:定义每个进程的最大需求
Allocation:定义每个进程现在已分配的各种资源类型的实例数量
Need:表示每个进程还需要的剩余的资源
Need[i][j]=Max[i][j]-Allocation[i][j]
举例:
解答:
Need[i][j]=Max[i][j]-Allocation[i][j]
Need矩阵:
A B C D
P0 0 0 0 0
P1 0 7 5 0
P2 1 0 0 2
P3 0 0 2 0
P4 0 6 4 2
我们可以测试是否能找出一个安全序列。
从P0开始,Available={1,5,2,0}
对P0,可以分配,然后收回,此时Available={1,5,3,2}
对P1,不能分配,跳过
对P2,可以分配,然后收回,此时Available={2,8,8,6}
对P3,可以分配,然后收回,此时Available={2,14,11,8}
对P4,可以分配,然后收回,此时Available={2,14,12,12}
对P1,可以分配,然后收回,此时Available={3,14,12,12}
最终,我们可以得到一个安全序列{P0,P2,P3,P4,P1}
证明当前系统是安全的
可以被满足,满足以后,Available矩阵等于{1,1,0,0}
可以找到一个安全序列{P0,P2,P3,P1,P4},完成运行
现在来验证一下:
对P0,可以分配,然后收回,此时Available={1,1,1,2}
对P1,不能分配,跳过
对P2,可以分配,然后收回,此时Available={2,4,6,5}
对P3,可以分配,然后收回,此时Available={3,10,9,7}
对P1,可以分配,然后收回,此时Available={4,10,9,7}
对P4,可以分配,然后收回,此时Available={4,10,10,11}
死锁检测
等待图:资源分配图中,删除所有资源类型节点,合并适当边。
如果所有资源类型只有单个实例,那么可以这样定义死锁检测算法:
当且仅当等待图中有一个环,系统存在死锁。
死锁恢复
进程终止
- 终止所有死锁进程。
代价:一些进程可能计算了很长时间 - 一次只终止一个进程直到取消死锁循环为止
代价:开销大,每次终止一个进程,都必须调用死锁检测算法确定进程是否仍处于死锁。
资源抢占
通过资源抢占以取消死锁,逐步从进程中抢占资源给其他进程使用,直至死锁结束。
有三个问题:
- 选择一个牺牲品,抢占哪些资源和哪个进程。
- 回滚:从其他进程抢占资源仍然不能正常执行,必须回滚到某个安全状态。最有效的方法是将进程回滚到打破死锁。
- 饥饿:成为牺牲品的进程可能永远不能完成任务;
解决:确保一个进程只能有限地被选择为牺牲品
习题
题目一
(1)请说明这个实例中死锁的 4 个必要条件
(2)请设计一条简单的规则来避免产生死锁
解答
(1)
- 互斥,车道的每一个位置只能有一辆车,一个位置不能同时被两辆车享。
- 占有并等待,当前车辆都占有自己当前车道的位置,并且等待下一个位置,下一个位置则被另外的车辆占有。
- 非抢占,一辆车占有的位置不能被抢占,即不能被移开
- 循环等待,图中的车辆可以看成一个序列,每一辆车都在等待下一辆车的位置,造成循环等待。
(2)在四个路口均设立红绿信号灯,要求在前30秒仅允许横向车辆通过,后30秒仅允许纵向车辆通过,然后以此顺序进行轮转。
题目二:
假设系统中有四个相同类型的资源被三个进程共享。每个进程最多需要两个资源。证明这个系统不会死锁。
解答:
假设该系统陷入死锁。这意味着,每一个进程持有一个资源,并且正等待另一个资源。因为有三个进程和四个资源,一个进程就必须获取两个资源。这一进程并不需要更多的资源,因此当其完成时会返回其资源。
通解:一个系统包含b个进程,共享同一类型的资源a个,每个进程最多需要c个该类型的资源;假设此时一个进程已经分配了c个该类型的资源,另外b-1个进程分配了c-1个该类型的资源,那么只需要满足(b-1)*(c-1)+c=b(c-1)+1<=a即可以不发生死锁。
题目三:
现有单实例资源系统:进程 P1 占有资源 R2,请求资源 R1;进程 P2 占有资源 R1,请求资源 R3 R4 R5;进程 P3 占有资源 R4,请求资源 R5;进程 P4 占有资源 R5,请求资源 R2;进程 P5 占有资源 R3,请求资源 R1;
(1)请画出对应的资源分配图和资源等待图;
(2)请问该系统中存在死锁吗?并请给出解释。
解答:
(1)
资源分配图:
资源等待图:
(2)
存在死锁,进程P1、P2、P4构成了一个有向环;进程P1、P2、P3、P4构成了一个有向环;P2、P5也构成了一个有向环;
P4等待P1占有的资源R2,P1等待P2占有的资源R1,P2等待P4占有的资源R5。
P4等待P1占有的资源R2,P1等待P2占有的资源R1,P2等待P3占有的资源R4,P3等待P5占有的资源P4。
P2等待P5占有的资源R3,P5等待P2占有的资源R1。