0x11 死锁

一、死锁概念及其资源分配图

过桥例子

在这里插入图片描述
桥只能一个方向通行;
桥的每一个部分都可以看成资源;
如果死锁发生,可能很多车都无法通行;
解决方法:可由一辆车返回解决(抢占资源并回退);
有可能产生饥饿。

死锁概念:

在多道程序环境下,一组处于等待状态的进程,其中每一个进程都持有资源。并且等待着由这组中其他进程所持有的资源,那么该组等待进程有可能再也无法改变其状态,这种情况称为死锁。

所有的死锁进程如果没有外力的介入,都无法向前推进。

引起死锁的主要原因:

(1)竞争互斥资源;
(2)进程推进不当。

例如,系统有两个磁带设备,进程P1和P2各占有一个磁带设备,并且实际需要两个磁带设备,此时P1和P2均死锁。
两个磁带设备是互斥资源。

死锁的特征(必要条件)

  1. 互斥:一次只有一个进程可以使用一个资源
  2. 占有并等待:一个至少持有一个资源的进程等待获得额外的由其他进程所持有的资源
  3. 不可抢占:一个资源只有当持有它的进程完成任务后,自由的释放
  4. 循环等待:等待资源的进程之间存在环{P0,P1,.…,P0}
    P0等待P1占有的资源,P1等待P2占有的资源,…,Pn-1等待Pn占有的资源,Pn等待P0占有的资源。

四个条件同时出现,死锁将会发生。

系统模型

为了研究死锁,建立系统模型。

资源类型的例子:
内存空间、CPU周期、文件、I/O设备等。
形式化表示为:资源类型R1,R2,…, Rm

进程使用资源顺序:

  • 申请资源
    分为动态申请资源和静态申请资源;
    动态申请资源,即在进程运行中申请资源;
    静态申请资源,即在进程运行前一次性申请所有资源。
  • 使用资源
  • 释放资源

资源分配图

一个顶点的集合V和边的集合E

  • V被分为两个部分
    P={P1,P2…,Pn},含有系统中全部的活动进程
    R={R1,R2,…,Rm},含有系统中全部的资源
  • 请求边:由进程Pi到资源Rj的有向边记为Pi→Rj,表示进程Pi申请了资源Rj的一个实例,该边称为申请边;
  • 分配边:由资源Rj到进程Pi的有向边记为Rj→Pi,表示资源Rj的一个实例已经分配给选程Pi,该边称为分配边。

在这里插入图片描述
例子:
在这里插入图片描述
如果分配图没有环,那么系统就没有进程死锁;
如果有环,那么可能存在死锁。

有环有死锁的资源分配图

在这里插入图片描述
系统中有最小的两个环, 此时进程P1,P2,P3死锁。
在这里插入图片描述

有环但没有死锁的资源分配图

在这里插入图片描述
因为进程P4可能释放R2的实例,这个资源可分配给P3,打破了环。

结论:

  1. 如果图没有环,那么不会有死锁
  2. 如果图有环,
  • 如果每一种资源类型只有一个实例,那么死锁发生
  • 如果一种资源类型有多个实例,可能死锁

处理死锁的方法

  1. 可使用协议来预防或避免死锁,确保系统不会进入死锁状态。
    系统可以采用死锁预防或死锁避免方案。
  2. 可允许系统进入死锁状态,然后检测它,并加以恢复。
    系统可提供死锁检测算法,并提供死锁灰复算法从死锁中恢复。
  3. 可忽略这个问题,认为死锁不可能在系统内发生。
    此方法为绝大多数操作系统所采用,包括Unix、Windows,因此需要由应用程序的开发人员自己来处理死锁。

二、死锁预防

死锁预防(deadlock prevention)是一组方法。只要确保至少一个必要条件不成立,抑制死锁发生的必要条件(互斥、占有并等待、非抢占、循环等待),就能预防死锁。

死锁的预防1

  • 非共享资源(互斥资源),必须要有互斥条件;
  • 共享资源,不涉及死锁;
  • 现代操作系统中的虚化技术,将互斥资源改造为共享资源;
  • 互斥:如系统存在互斥资源,不能改变这个条件来预防死锁。

死锁的预防2

占有并等待:必须保证进程申请资源的时候没有占有其他资源
静态分配策略;
一种可用的协议是每个进程在执行前一次性申请并获得所有资源。
另外一种协议则允许进程在没有资源时才可申请资源。

在这里插入图片描述
按照第一种协议,进程一开始就要申请DVD驱动器、磁盘、打印机,在其执行期间他始终占有打印机。
第二种协议允许进程开始时只申请DVD驱动器、磁盘,复制完数据后,释放这两个设备,然后再申请磁盘和打印机,当数据打印完后,再释放资源并终止。

缺点:

  1. 资源利用率低
    许多资源可能已分配,但很长时间没有被使用。

  2. 可能发生饥饿
    一个进程如果需要多个常用资源,可能会永久等待,因为其所需要的资源中,至少有一个已分配给其他资源。

死锁的预防3

非抢占:
如果一个进程的申请没有实现,它要释放所有占有的资源。
先占的资源放入进程等待资源列表中;
进程在重新得到旧的资源的时候可以重新开始。
在这里插入图片描述

死锁的预防4

循环等待:
对所有的资源类型排序进行总排序,并且要求进程按照递增顺序申请资源。

设R={R1,R2,…, Rm)为资源类型的集合,为每个资源类型分配一个唯一整数来允许比较两个资源以确定其顺序。

为预防死锁,每个进程只按递增顺序申请资源,即一个进程开始可以申请任何资源类型Ri的实例。
当且仅当Rj的值大于Ri的值时,进程才可以申请Rj的实例。
在这里插入图片描述
一个进程如果同时需要使用磁带驱动器和打印机,那就必须先申请磁带驱动器,再申请打印机。

设计一个完全排序方法并不能防止死锁,而要靠应用程序员来按照顺序编写程序。
各资源类型的序号确定也是至关重要的,一般要按照系统内部资源使用的正常顺序定义。

三、死锁避免

死锁避免

死锁预防算法
操作:通过限制资源申请的方法来预防死锁
副作用:降低了设备使用率和系统吞吐量。

避免死锁的另一个方法:
获得以后如何申请资源的附加信息来决定是否分配资源。
每次申请要求系统考虑现有可用资源、现已分配给每个进程的资源和每个进程将来申请与释放的资源,以决定申请是否满足,从而避免死锁发生的可能性。

最为简单和最为有用的模型要求进程说明可能需要的每种资源类型实例的最大需求。

需要系统有一些额外的信息:

  • 一个简单而有效的模型要求每一个进程声明它所需要的资源的最大数
  • 死锁避免算法动态检查资源分配状态以确保循环等待条件不可能成立
  • 资源分配状态定义为可用的与已分配的资源数,和进程所需的最大资源量所决定

这里的资源分配状态是由可用资源和已分配资源、及进程最大需求所决定的。

安全状态

当进程申请一个有效的资源的时候,系统必须确定分配后是安全的。
如果存在一个安全序列,系统处于安全态。

进程序列<P1,P2,…,Pn>是安全的,如果每一个进程Pi所申请的可以被满足的资源数加上其他进程所持有的该资源数小于系统总数。

  • 如果Pi需要的资源不能马上获得,那么Pi等待直到所有的Pi-1进程结束;
  • 当Pi-1结束后,Pi获得所需的资源,执行、返回资源、结束;
  • 当Pi结束后,Pi+1获得所需的资源执行,依此类推。

安全状态与死锁状态的关系

安全状态不是死锁状态,相反,死锁状态是不安全状态。

  • 如果一个系统在安全状态,就没有死锁
  • 如果一个系统不是处于安全状态,就有可能死锁
  • 死锁避免→确保系统永远不会进入不安全状态
    采用这种方案,如果进程申请一个现已可用的资源,它有可能必须等待。因此,与没有采用死锁避免算法相比,这种情况下资源利用率可能更低。

避免算法

  1. 如果有一个系统,每种资源类型只有一个实例,
    单实例资源
    资源分配图法:
    在原资源分配图中,除了申请边和分配边外,引入一种新类型的边,称为需求边。
  • 需求边Pi→Rj: Pi可能以后需要申请Rj资源,用虚线表示;
  • Pi申请Rj资源,需求边转换为请求边;
  • 请求边在资源分配后转换为分配边;
  • 资源释放后,分配边转换为需求边。

假设Pi申请资源Rj
请求能满足的前提是:把请求边转换为分配边后不会导致环存在
在这里插入图片描述
如果P2申请资源R2,虽然R2可用,但是不能分配资源给P2,因为这样会创建一个环,环表示系统处于不安全状态。

从算法效率上讲,环检测算法需要n2级的操作。其中n是图中节点数,也就是系统中进程数量。

  1. 对于每种资源类型有多个实例的系统,
    多实例资源
    银行家算法(效率比资源分配图法要低)
  • 多个实例;
  • 每一个进程必须事先声明使用的最大量;
  • 当一个进程请求资源,它可能要等待;
  • 当一个进程得到所有的资源,它必须在有限的时间释放它们。

为了实现银行家算法,必须有几个数据结构,这些结构对系统的状态进行了记录,其中n为系统进程的个数,m为资源类型的种类。

银行家算法的数据结构

  • Available:长度为m的向量。如果available[j]=k,那么资源Rj有k个实例有效;
  • Max:n*m矩阵。如果Max[i,j]=k,那么进程Pi最多可以请求k个资源Rj的实例;
  • Allocation:n*m矩阵。如果Allocation[i,j]=k,那么进程Pi当前分配了k个资源Rj的实例;
  • Need:n*m矩阵。如果Need[i,j]=k,那么进程Pi还需要k个资源Rj的实例;
    Need[i,j] = Max[i,j] - Allocation[i,j]

安全算法

  1. 让Work和Finish作为长度为m和n的向量初始化:
    Work:=Available
    Finish[i]=false for i-1,3,……,n.
  2. 查找i
    (a)Finish[i]=false
    (b)Needi ≤ Work
    If no such i exists,go to step 4.
  3. Work:=Work+Allocation,
    Finish[i]:=true
    go to step 2.
  4. 如果对所有i的Finish[i]=true,则系统处在安全状态。

是否满足进程Pi的资源请求算法:
Requesti=进程Pi的资源请求向量。如果Requesti[m]=k,则进程Pi想要资源类型为Rjm的k个实例

  1. 如果Requesti ≤ Needi,转step2. 否则报错,因为进程请求超出了其声明的最大值;
    2.如果Requesti ≤ Available,转step3. 否则Pi必须等待,因为资源不可用.
  2. 假设通过修改下列状态来分配请求的资源给进程Pi
    Available:=Avalilable-Requesti;Alocationi:=Alocationi+Requesti;Needi:=Needi-Requesti
    如果系统安全→将资源分配给Pi
    如果系统不安全→Pi必须等待,恢复原有的资源分配状态。

银行家算法的例子
在这里插入图片描述
现在假设P1请求一个资源类型A和两个资源类型C,即Request1=(1,0,2)
在这里插入图片描述

四、死锁检测和解除

允许系统进入死锁状态,也就是说系统既不采用死锁预防算法也不采用死锁避免算法,然后检测死锁并恢复系统。
系统应该提供:一个用来检测系统是否出现了死锁的算法和一个用来从死锁状态中恢复的算法。

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

  • 维护等待图:
    节点是进程,
    Pi→Pj表明Pi在等待Pj
  • 定期调用算法来检查是否有环
  • 一个检查图中是否有环的算法需要n2的操作来进行,n为图中的节点数

一个资源类型的多个实例

  • Available:一个长度为m的向量,表示每一种资源类型可用的实例数目
  • Allocation:一个n*m的矩阵,定义了当前分配的每一种资源类型的实例数目
  • Request:一个n*m的矩阵,表明了当前的进程请求。如果Request[i,j]=k,那么进程Pi请求k个资源Rj的实例

检测算法的具体步骤

  1. 让Work和Finish作为长度为m和n的向量初始化
    (a)Work=Available
    (b)For i=0,2.…,n-1,if Allocation ≠ 0,thenFinish[i]=false;otherwise,Finish[i]=true.
  2. 找到满足下列条件的下标i
    (a)Finish[i]=false
    (b)Requesti ≤ Work
    如果没有这样的i存在,转4
  3. Work=Work +Allocationi
    Finish[i]=true
    转2.
  4. 如果有一些i(0 ≤ i ≤ n),Finish[i] = false,则系统处在死锁状态。而且,如果Finish[i]=false,则进程Pi是死锁的。

算法需要m*n2次操作来判断是否系统处于死锁状态。

检测算法的例子

在这里插入图片描述
在这里插入图片描述

检测算法的用法

何时及多长时间的调用取决于:

  • 死锁可能发生的频率
  • 有多少进程受影响

每个请求都调用;

因此极端情况下,每次请求不能立即满足时,就调用死锁检测算法。

对于每个请求都调用检测算法,会引起相当大的开销。所以可以使用不太高的频率调用算法,如每小时一次,或当CPU使用率低于40%时。
如果检测算法被随意的调用,可能图中存在很多的环以至于无法判断是哪一个进程引起了死锁的发生。

死锁恢复

  1. 人工恢复
    通知操作员,人工处理
  2. 自动恢复
    (1)终止进程
    会收回分配给被终止进程的所有资源。
    中断所有的死锁进程;
    一次中断一个进程直到死锁环消失。
    影响选择进程的因素:
    进程的优先级;
    进程需要计算多长时间,以及需要多长时间结束;
    进程使用的资源;
    进程完成还需要多少资源;
    多少个进程需要被终止;
    进程是交互的还是批处理;

(2)抢占资源

  1. 选择一个牺牲品:最小化代价
    包含如所拥有的资源数、运行到现在的时间等。
  2. 回滚:返回到安全的状态,然后重新开始进程。
  3. 饥饿:同样进程的可能总是被选中,在代价因素中加入回滚次数。

猜你喜欢

转载自blog.csdn.net/ITmincherry/article/details/106667407