银行家算法实现——找出所有安全序列
一 .死锁概述
所谓死锁: 是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。——百度百科
通俗的说,A进程持有资源a,还需要资源b,B进程持有资源b,还需要资源a,在无其他外界条件下,A进程需要B进程资源,B进程需要A进程资源,谁也不肯放手,我们就说这时出现死锁。
解决死锁问题主要通过预防死锁,避免死锁,检测死锁,解除死锁四个方面。
二. 银行家算法
银行家算法是从避免死锁来解决死锁问题。
1. 数据结构
available[m] //m种资源,每种资源可用数目
max[i][j] //第i个进程第j种资源最大需求量
allocation[i][j] //第i个进程第j种资源已经分配的量
need[i][j] //第i个进程第j种资源还需要的量
由上可以看出 max[i][j] = allocation[i][j] + need[i][j]
2. 算法步骤
设requesti是Pi的请求向量
若request[j]>need[i][j],程序报错
若request[j]>available[i][j],系统资源数不够,进程陷入等待
系统尝试着把资源分配给进程i,修改如下数据
available[j] -= request[j]
allocation[i][j] += request[j]
need[i][j] -= request[j]
接下来运行安全性算法
设置工作向量work[m],表示系统目前的各类资源数,初始work=available
finish[n],表示该进程是否在安全性队列中,初始finish[i] = false
从进程集合中找出一个满足下列条件的进程:
finish[i] = false,need[i][j] <= work[j]
若找到,修改下列值:
finish[i] = true
work[i] += allocation[i][j]
继续寻找下一个满足的进程
若所有的finish[i] = true,表示系统处于安全性状态,之前提出的请求可以满足。
3. 程序实现
我们先看一下安全性算法的c++代码
void isSafe()
{
int i, j, k;
for(i=1; i<=n; i++) //安全性序列要选n个进程
{
for(j=0; j<n; j++) //每次选择从n个进程里选一个
{
bool pd = true;
if(finish[j]){
continue;
}
for(k=0; k<m; k++) //每次选择要判断m个资源
{
if(work[k] < need[j][k]) //若有一个资源不满足,则break,寻找下一个进程
{
pd = false;
break;
}
}
if(pd){
ans.push_back(j);
finish[j] = true;
for(k=0; k<m; k++){ //选完j进程后,把已分给j进程的资源收回
work[k] += allow[j][k];
}
break;
}
}
if(j >= n){
break;
}
}
if(i > n){
for(j=0; j<ans.size(); j++)
{
cout << "P" << ans[j] << ",";
}
cout << endl;
sum++;
}
}
主体为三重循环,时间复杂度为O(n*n*m),第一层循环代表安全序列里要有n个