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 发出资源请求后,系统按如下步骤进行检查:
- 如
Requesti[j] ≤ Need[i,j]
,转(2);否则出错,因为进程申请资源量超过它声明的最大量。 - 如
Requesti[j] ≤ Available[j]
,转(3);否则表示资源不够,需等待。 - 系统试分配资源给进程Pi,并作如下修改:
Available[j] = Available[j]- Requesti[j]
Allocation[i,j] = Allocation[i,j]+ Requesti[j]
Need[i,j] = Need[i,j]- Requesti[j] - 系统执行
安全性算法
,检查此次资源分配后,系统是否处于安全状态。若安全,则正式进行分配,否则恢复原状态,让进程Pi等待。
2.2.2、安全性检查算法
为了进行安全性检查,需要定义如下数据结构:
int Work[m]
工作变量,记录可用资源。开始时, Work = Available
boolean Finish[n]
工作变量,记录进程是否执行完。开始时,Finish[i]=false
,当有足够资源分配给进程Pi时,令Finish[i]=true
。
Work = Available
Finish[i] = false- 寻找满足如下条件的进程Pi
Finish [i] = false
并且Need[i,j] ≤ Work
如果找到,转(3),否则转(4) - 当进程Pi获得资源后,可顺利执行完,并释放分配给它的资源 ,故执行:
Work = Work + Allocation
Finish[i] = true
转 (2). - 若所有进程的
Finish [i] = true
,则表示系统处于安全状态,否则处于不安全状态。