[操作系统基础]死锁的预防和避免

1、死锁的预防

1.1、破坏互斥条件(不可行)

即允许多个进程同时访问资源。但由于资源本身固有特性限制,有的资源根本不能同时访问,只能互斥访问,所以不可能用破坏互斥条件来预防死锁。

1.2、破坏请求和保持条件

可采用预先静态分配方法,即要求进程在运行之前一次申请它所需要的全部资源,在它的资源未满足前,不把它投入运行。一旦运行后,这些资源全归其占有,同时它也不再提出其它资源要求,这样可以保证系统不会发生死锁。
此方法虽简单安全,但降低了资源利用率,同时必须预知进程所需要的全部资源。

1.3、破坏不可剥夺条件

一个已经获得某些资源的进程,若又请求新的资源时不能得到满足,则它必须释放出已获得的所有资源,以后需要资源时再请求。即一个进程已获得的资源在运行过程中可被剥夺。从而破坏了“不剥夺”条件。
这种方法实现较复杂,会增加系统开销,降低系统吞吐量。

1.4、破坏环路条件

可采用有序资源分配方法,即将系统中的所有资源都按类型赋予一个编号,要求每一个进程均严格按照编号递增的次序来请求资源,同类资源一次申请完。也就是,只要进程提出请求资源Ri,则在以后的请求中,只能请求Ri后面的资源,这样不会出现几个进程请求资源而形成环路。
该方法虽提高了资源的利用率,但编号难,加重进程负担及因使用资源顺序与申请顺序不同而造成资源浪费。

2、死锁的避免

在死锁预防的几种方法中,都施加了较强的限制条件,严重降低了系统性能。
在死锁避免的方法中,所施加的限制条件较弱,对于进程发出的每一个资源申请命令实施动态检查,并根据检查结果决定是否实施资源分配。
在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终处于安全状态,便可以避免死锁的发生。

2.1、安全状态

指在某一时刻,系统能按某种进程顺序(P1,P2,…,Pn)来为每个进程Pi分配其资源,直到满足每个进程对资源的最大需求,使每个进程都可顺利地完成,称此时的系统状态为安全状态,称序列(P1,P2,…,Pn)安全序列
若某一时刻系统中不存在这样一个安全序列,则称此时的系统状态为不安全状态

  • 如果一个系统在安全状态,就没有死锁
  • 如果一个系统处于不安全状态,就有可能死锁
  • 避免死锁的实质:确保系统不进入不安全状态

2.2、避免死锁的算法-银行家算法

具有代表性的避免死锁算法,是Dijkstra给出的银行家算法,为实现银行家算法,系统中必须设置若干数据结构。假定系统中有n个进程(P1,P2,…,Pn),m类资源(R1,R2,…,Rm),银行家算法中使用的数据结构如下:

  • 可利用资源向量:available[j]=k, 资源Rj类有k个可用
  • 最大需求矩阵:Max[i,j]=k,进程Pi最大请求k个Rj类资源
  • 分配矩阵:Allocation[i,j]=k,进程Pi分配到k个Rj类资源
  • 需求矩阵:Need[i,j]=k,进程Pi还需要k个Rj类资源

三个矩阵之间的关系Need [i,j] = Max[i,j] – Allocation [i,j]

2.2.1、资源分配算法

设Requesti是进程Pi的请求向量,设Requesti [j] =k,表示进程Pi请求分配Rj类资源k个。当进程Pi 发出资源请求后,系统按如下步骤进行检查:

  1. Requesti[j] ≤ Need[i,j],转(2);否则出错,因为进程申请资源量超过它声明的最大量。
  2. Requesti[j] ≤ Available[j],转(3);否则表示资源不够,需等待。
  3. 系统试分配资源给进程Pi,并作如下修改:
    Available[j] = Available[j]- Requesti[j]
    Allocation[i,j] = Allocation[i,j]+ Requesti[j]
    Need[i,j] = Need[i,j]- Requesti[j]
  4. 系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,则正式进行分配,否则恢复原状态,让进程Pi等待。

2.2.2、安全性检查算法

为了进行安全性检查,需要定义如下数据结构:

int Work[m] 工作变量,记录可用资源。开始时, Work = Available
boolean Finish[n] 工作变量,记录进程是否执行完。开始时,Finish[i]=false,当有足够资源分配给进程Pi时,令Finish[i]=true

  1. Work = Available
    Finish[i] = false
  2. 寻找满足如下条件的进程Pi
    Finish [i] = false 并且 Need[i,j] ≤ Work
    如果找到,转(3),否则转(4)
  3. 当进程Pi获得资源后,可顺利执行完,并释放分配给它的资源 ,故执行:
    Work = Work + Allocation
    Finish[i] = true

    转 (2).
  4. 若所有进程的Finish [i] = true ,则表示系统处于安全状态,否则处于不安全状态。

猜你喜欢

转载自blog.csdn.net/wayway0554/article/details/79892226
今日推荐