[OS] 死锁相关知识点以及银行家算法详解

因此我们先来介绍一下死锁:

死锁特征

  当出现死锁时,进程永远不能完成,并且系统资源被阻碍使用,阻止了其他作业开始执行。在讨论处理死锁问题的各种方法之前,先深入讨论一下死锁的特征。

·必要条件

(1)互斥:至少有一个资源必须处于非共享模式,即一次只有一个进程使用。如果另一进程申请该资源,那么申请进程必须等到该资源被释放为止。

(2)占有并等待:一个进程必须占有至少一个资源,并等待另一资源,而该资源为其他进程所占有。

(3)非抢占:资源不能被抢占,即资源只能在进程完成任务后自动释放。

(4)循环等待:有一组等待进程{P0,P1,···,Pn},P0等待的资源为P1所占有,P1等待的资源为P2所占有,...,Pn-1等待的资源为Pn所占有,Pn等待的资源为P0所占有。

  注:强调所有4个条件必须同时满足才会出现死锁。循环等待意味着占有并等待,这样四个条件并不完全独立。但是,在下面的讨论中我们会看到分开考虑这些条件是有意义的。

·资源分配图

  死锁问题可用系统资源分配图的有向图进行更为精确的描述。这种图由一个结点集合V和一个边集合E组成。

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

  在图上,用圆形表示进程Pi,用矩形表示资源类型Rj。由于资源类型Rj可能有多个实例,所以在矩形中用圆点表示实例。注意申请边只指向矩形Rj,而分配边必须指定矩形内的某个圆点。

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

      

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

由上图可知,资源分配图有环不一定会产生死锁。

死锁处理方法

·可使用协议以预防或避免死锁,确保系统不会进入死锁状态。

·可允许系统进入死锁状态,然后检测它,并加以恢复。

·可忽视这个问题,认为死锁不可能在系统内发生。

死锁预防

我们已经知道,出现死锁要满足4个必要条件,只要确保一个必要条件不成立,就能预防死锁发生。下面通过讨论这4个必要条件来研究死锁预防方法。

互斥:共享资源不是必须的,而非共享资源必须保持互斥
占有并等待:必须保证进程申请资源的时候没有占有其他资源
  ·要求进程在执行前一次申请全部的资源,只有没有占有资源时才可以分配资源
  ·利用率低,可能出现饥饿
非抢占:如果一个进程的申请没有实现,它要释放所有占有的资源
循环等待:将所有的资源类型放入资源列表中,并且要求进程按照资源表中递增的顺序申请资源

死锁避免

  上面我们讨论的死锁预防算法中,通过限制资源申请的方法来预防思索。这种限制确保4个必要条件之一不会发生,因此死锁不成立。然而,通过这种方法预防死锁的副作用是低设备使用率和系统吞吐率。

·安全状态

  系统安全指存在一个执行序列,所有进程都能完成,这个序列被称为安全序列。下面来举一个例子:

系统有三个进程P1、P2和P3,共有12台打印机。
进程P1总共要求10台打印机,P2和P3分别要求4台和9台
假定T0时刻,进程P1、P2和P3已分别获得5台、2台和2台,尚有3台空闲未分,如下表:

可以看出,存在一个安全序列P2、P1、P3,所以说T0时刻是系统安全的。

  安全状态不是死锁状态。相反,死锁状态是不安全状态。然而,不是所有不安全状态都能导致死锁状态。不安全状态可能导致死锁。系统可以从安全状态转换为不安全状态。

  有了安全状态的概念,可定义避免算法以确保系统不会死锁。其思想是简单地确保系统始终处于安全状态。开始,系统处于安全状态。当进程申请一个可用的资源时,系统必须确定这一资源申请是可以立即分配还是等待。只有分配后使系统仍处于安全状态,才允许申请。

  采用这种方案,如果进程申请一个现已可用的资源,那么它可能必须等待。因此,与没有采用死锁避免算法相比,这种情况下资源使用率可能更低。

·资源分配图算法(适用于每种资源类型只有一个实例)

  该算法是在资源分配图的基础上,引入一新类型的边,称为需求边。需求边Pi->Rj表示进程Pi可能在将来某个时候申请资源Rj。这种边类似于同一方向的申请边,但用虚线表示。当申请资源时,需求边变为申请边;释放资源时,申请边变为需求边。

  假设进程Pi申请资源Rj。只有在将申请边Pi->Rj变为分配边Rj->Pi而不会导致资源分配图形成环时,才允许申请。

 

·银行家算法(适用于每种资源类型有多个实例

为了实现银行家算法,必须要有几个数据结构:

注:设n为系统进程的个数,m为在资源类型的种类。

Available长度为m的向量。表示每种资源的现有实例的数量。如果Available[j]=k,那么资源Rj有k个实例有效。

Maxn * m矩阵。定义每种进程的最大需求。如果Max[i][j]=k,那么进程Pi可以最多请求资源Rj的k个实例。

Allocationn * m矩阵。定义每个进程现在所分配的各种资源类型的实例数量。如果Allocation[I,j]=k,那么进程Pj当前分配了k个资源Rj的实例。

Needn * m矩阵。表示每个进程还需要的剩余的资源。如果Need[i][j]=k,那么进程Pj还需要资源Rj的k个实例。
注:Need[i][j] = Max[i][j] – Allocation [i][j]

为了描述方便,我们采用一些简化的表示方法:

  设X和Y为长度为n的向量,则X <= Y当且仅当对所有i = 1,2,...,n,X[i] <= Y[i]。例如,如果X = (1,7,2,3)而Y = (0,3,2,1),那么Y <= X。如果Y <= X且Y != X,那么Y < X。

  可以将AllocationNeed的每行作为向量,并分别用Allocation i和Need i来表示,向量Allocation i表示分配给进程Pi的资源;向量Need i表示进程为完成其任务可能仍然需要申请的额外资源。

银行家算法可整体分成两个部分:

1.安全性算法

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

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

(2)查找这样的i使其满足

  ·Finish[i] = false

  ·Need i <= Work

  如果没有这样的i,那么就转到第(4)步。

(3)Work = Work + Allocation i

   Finish[i] = true

   返回第(2)步

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

该算法可能需要m * n^2数量级的操作以确定系统是否处于安全状态。

2.资源请求算法

现在,描述如何判断是否可安全允许请求的算法。

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

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

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

(3)假定系统可以分配给进程Pi所请求的资源,并按如下方式修改状态:

   AvailableAvailableRequest i;

   Allocation i = Allocation i + Request i;

   Need i = Need i - Request i;

  如果所产生的资源分配状态是安全的(通过上面的安全性算法),那么Pi可分配到它所请求的资源。但是,如果新状态不安全,则进程Pi必须等待Request i并恢复到原来的资源分配状态。

 

上面都是一些表达式,可能有些枯燥,现在我们来练习一道例题:

  考虑这样一个系统,有5个进程P0~P4,3种资源类型A、B、C。资源类型A有10个实例,资源类型B有5个实例,资源类型C有7个实例。假定在时刻T0,系统状态如下:

		Allocation		Max		Avaliable
		 A  B  C      A  B  C    A  B  C
P0		 0  1  0      7  5  3    3  3  2
P1       2  0  0      3  2  2   
P2       3  0  2      9  0  2
P3       2  1  1      2  2  2
P4       0  0  2      4  3  3

  矩阵Need的内容定义成Max-Allocation

 	   	  Need
		 A  B  C
P0		 7  4  3
P1       1  2  2
P2       6  0  0
P3       0  1  1
P4       4  3  1

  可认为系统现在处于安全状态,因为存在一个安全序列<P1,P3,P4,P2,P0>。

  现在假定进程P1再请求1个A类资源和两个C类资源,这样Request1 = (1,0,2)。为了确定这个请求是否可以立即允许,首先检测Request1 <= Available(即,(1,0,2) <= (3,3,2)),其值为真。接着假定这个请求被满足,会产生如下新状态:

		Allocation	   Need		Avaliable
		 A  B  C      A  B  C    A  B  C
P0		 0  1  0      7  4  3    2  3  0
P1       3  0  2      0  2  0   
P2       3  0  2      6  0  0
P3       2  1  1      0  1  1
P4       0  0  2      4  3  1

  必须确定这个状态是否安全。为此,执行安全算法,并找到顺序<P1,P3,P4,P0,P2>满足安全要求。因此,可以立即允许进程P1的这个请求。

  然而,可以发现当系统处于这一状态时,是不能允许P4的请求(3,3,0)的,因为没有那么多资源可用。也不能允许P0的请求(0,2,0);虽然有资源可用,但是这会导致系统处于不安全状态。

 

posted @ 2017-03-27 20:11  Strawberry丶  阅读(5105)  评论(0编辑  收藏  举报