死锁

死锁

死锁特征

死锁的必要条件

如果在一个系统中下面4个条件同时满足,那么会引起死锁。
1.互斥:至少有一个资源必须处于非共享模式。
2.占有并等待:一个进程必须占有至少一个资源,并等待另一资源。
3.非抢占:资源不能被抢占,即资源只能在进程完成任务后自动释放。
4.循环等待:有一组等待进程{P1,P2,…,Pn},P1等待的资源被P2所占有,P2等待的资源被P3所占有,…,Pn等待的资源被P1所占有。

资源分配图

死锁问题可用称为系统资源分配图的有向图进行更为精准地描述。这种图由一个节点集合V和一个边集合E组成。节点集合V可分成两种类型的节点:P={P1,P2,…,Pn}(系统活动进程的集合)和R={R1,R2,…,Rm}(系统所有资源类型的集合)。

由活动进程Pi到资源类型Rj的有向边记为Pi -> Rj,它表示进程Pi已经申请了资源类型Rj的一个实例,并正在等待该资源。由资源类型Rj到进程Pi的有向边记为
Rj -> Pi,它表示资源类型Rj的一个实例已经分配给进程Pi。Pi -> Rj称为申请边,Rj -> Pi称为分配边

资源分配图

根据资源分配图的定义,可以证明:如果分配图没有环,那么系统就没有进程死锁。如果分配图有环,那么可能存在死锁。


死锁处理方法

从原理上来说,有三种方法可处理死锁:
1.可用使用协议以预防或避免死锁,确保系统不会进入死锁。
2.可允许系统进入死锁,然后检测它加以修复。
3.忽视该问题,认为死锁不可能发生

死锁预防(deadlock prevention)是一组方法,以确保至少一个必要条件不成立。

死锁避免(deadlock avoidance)要求操作系统事先得到有关进程申请资源和使用资源的额外信息。


死锁预防

通过对死锁产生的四个必要条件进行研究,找到预防死锁的办法。

互斥

如果资源是共享的,比如说只读文件,那么对这类型的资源的访问是不会造成死锁的。但很多资源本身就是非共享资源,所以通常不能通过否定互斥这一条件来预防死锁。

占有并等待

为了确保占有并等待的情况不在系统内出现,必须保证:当一个进程申请资源时,本身不能占有任何资源(进程不占有资源);或者,进程在执行前申请并获得所有资源(进程不等待资源)。

这种做法由两个主要缺点:
1.资源利用率低
2.可能造成饥饿

非抢占

为了确保这一条件不成立,可以使用如下协议:如果一个进程占有资源并申请另一个不能立即分配的资源,那么其现已分配的资源都可被抢占。

这个协议通常应用于状态可用保存和恢复的资源,如CPU寄存器和内存。因为等待的进程取得期望资源后要将被抢占的资源恢复在继续执行。

循环等待

一个确保此条件不成立的方法是对所有资源类型进行完全排序,且要求每个进程按递增顺序来申请资源。一个进程开始可申请任何数量的资源类型Ri的实例,之后,当且仅当F(Rj) > F(Ri)时(F函数返回资源类型的等级),该进程可以申请资源Rj的实例。如果进程需要同一资源类型的多个实例,那么对它们必须一起申请。

换句话说,要求当一个进程申请资源类型Rj时,它必须释放所有资源Ri(F(Ri) >= F(Rj))。


死锁避免

死锁预防的副作用是降低了设备使用率和系统吞吐率。

通过获得进程以后如何申请资源的附加信息,可用通过算法来避免死锁。

不同的算法对于要求的信息量和信息的类型有所不同。最为简单和最为有用的模型要求每个进程说明可能需要的每种资源类型实例的最大需求。根据这些事先信息,可用构造一个算法以确保系统不会进入死锁状态。

死锁避免算法动态地检测资源分配状态以确保循环等待条件不可能成立。

安全状态

如果系统能按某个顺序为每个进程分配资源(不超过其最大值)并能避免死锁,那么系统状态就是安全的,这个顺序称为安全序列

进程顺序<P1,P2,…,Pn>,如果对于每个Pi,Pi需要申请的资源数小于当前可用资源加上所有进程Pj(j < i)所占有的资源(同一资源类型),那么这一顺序称为安全序列。如果没有这样的顺序存在,那么系统状态就处于不安全状态(可能陷入死锁)。

举个例子:

进程最大需求当前需求
P0105
P142
P292

如表所示,假设在t0时刻,总共有12台打印机,P0 占有了5台打印机,P1占有了2台打印机,P2占有了2台打印机,还有3台打印机空闲。那么顺序<P1,P0,P2>就是安全序列。进程P1,可以立即获得所需的两台打印机,然后将4台打印机释放,P0,P2同理。

系统可以从安全状态转换为不安全状态。假定在时刻t1,P2申请并又得到了1台打印机,就不会存在所谓的安全序列了。

有了安全状态的概念,可定义避免算法以确保系统不会死锁。只有资源分配后使系统仍处于安全状态的资源申请才会被允许。

资源分配图算法

如果每种资源类型只有一个实例,那么资源分配图有环就死锁,无环就没有死锁,那么通过避免环的产生,就能避免死锁的产生。

银行家算法

对于每种资源类型有多个实例的资源分配系统,资源分配图算法就不适用了。银行家算法能够解决这种问题。

当新进程进入系统时,它必须说明其可能需要的每种类型资源实例的最大数量,这一数量不能超过系统资源的总和。当用户申请一组资源时,系统必须确定这些资源的分配是否仍会使系统处于安全状态。

为了实现银行家算法,必须有几个数据结构。这些数据结构对资源分配系统的状态进行了记录。设n为系统进程的个数,m为资源类型的种类。需如下数据结构:
1.Available,长度为m的向量,表示每种资源的现有实例的数量。
2.Max,n×m矩阵,定义每个进程的最大需求。
3.Alloction,n×m矩阵,定义每个进程所在所分配的各种资源类型的实例数量。
4.Need,n×m矩阵,表示每个进程还需要的剩余资源。
Need[i][j] = Max[i][j] - Alloction[i][j]

这些数据结构的大小和值会随着时间而改变。

安全性算法

确定计算机系统是否处于安全状态的算法分为如下几步:

1.设 Work 和 Finish 分别为长度为 m 和 n 的向量。按如下方式进行初始化,
Work = Available 且 对于 i = 0,1,…,n-1,Finish[i] =false。

2.查找这样的 i 使其满足
a.Finish[i] == false
b. Need i <= Work (Need i 表示Need矩阵中下标为 i 那一行向量)
如果没有这样的 i 存在,那么转到第四步。

3.Work = Work + Allocation i
Finish[i] = true
返回到第二步。

4.如果对所有i,Finish[i] = true,那么系统处于安全状态。

这个算法可能需要 m × n^2 数量级的操作以确定系统状态是否安全(相当于寻找计算机系统中是否存在安全序列)。

资源请求算法

设 Request i 为进程Pi的请求向量。如果 Request i[j] == k,那么进程Pi需要的资源类型 Rj 的实例数量为 k。当进程Pi作出资源请求时,采取如下动作:

1.如果 Request i <= Need i,那么转到第二步。否则产生出出错条件,这是因为进程Pi已超过了其最大请求。

2.如果 Request i <= Available,那么转到第三步。否则Pi必须等待,这是因为没有可用资源。

3.假定系统可用分配给进程Pi所请求的资源,并按如下方式修改状态:
Available = Available - Request i;
Allocation i = Allocation i + Request i;
Need i = Need i - Request i;

如果所产生的资源分配状态是安全的,那么交易完成且进程Pi可分配到其所需要资源。然而,如果新状态不安全,那么进程Pi必须等待Request i并恢复到原来资源分配状态。


死锁检测

如果一个系统既不采用死锁预防算法也不采用死锁避免算法。那么可能会出现死锁。在这种环境下,系统应提供:
1.一个用来检查系统状态从而确定是否出现了死锁的算法。
2.一个用来从死锁状态中恢复的算法。

每种资源类型只有单个实例

如果所有资源类型只有单个实例,那么可以定义这样一个死锁检测方法,该算法使用了资源分配图的一个变种,称为等待图。从资源分配图中,删除所有资源类型节点,合并适当边,就可以得到等待图。

与以前一样,当且仅当等待图中有一个环,系统中存在死锁。

每种资源类型可有多个实例

同样,我们需要一些数据结构:
1.Available: 长度为m的向量,表示各种资源的可用实例。
2.Allocation:n×m矩阵,表示当前个进程的资源分配情况。
3.Request:n×m矩阵,表示当前各进程的资源请求情况。

检测步骤如下:

1.设 Work 和 Finish 分别为长度为 m 和 n 的向量。初始化 Work = Available。对于 i = 0,1,…,n - 1,如果 Allocation i 不为0,则 Finish[i] = false;否则,Finish[i] = true。

2.找到这样的 i,以便同时使
a.Finish[i] == false
b.Request i <= Work
如果没有这样的 i,则转到第四步。

3.Work = Work + Allocation i
Finish[i] = true
转到第二步

4.如果对某个 i(0 <= i < n),Finish[i] == false,则系统处于死锁状态。而且,如果 Finish[i] == false。则进程Pi死锁。

应用检测算法

应该何时调用检测算法?答案取决于两个因素:
1.死锁可能发生的频率是多少?
2.当死锁发生时,有多少进程会受影响?

如果经常发生死锁,那么就应该经常调用检测算法。以一个不太高的频率调用检测算法,如每小时一次,或当CPU使用率低于40%s时(死锁最红会使系统性能下降,并造成CPU使用率下降)。


死锁恢复

进程终止

有两种方法通过终止进程已取消死锁。
1.终止所有死锁进程。
2.一次只终止一个进程直到取消死锁循环为止。

资源抢占

通过抢占资源以取消死锁,逐步从进程中抢占资源给其他进程使用,直到死锁环被打破。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值