银行家算法
博客地址:https://www.iamzlt.com/?p=87
(一)目的和要求
银行家算法是由Dijkstra设计的最具有代表性的避免死锁的算法。本实验要求用高级语言编写一个银行家的模拟算法。通过本实验可以对预防死锁和银行家算法有更深刻的认识。
(二)实验内容
1、设置数据结构
包括可利用资源向量(Availiable),最大需求矩阵(Max),分配矩阵(Allocation),需求矩阵(Need)
2、设计安全性算法
设置工作向量Work 表示系统可提供进程继续运行可利用资源数目,Finish 表示系统是否有足够的资源分配给进程
(三)实验环境
- PC
- VC++
#include<iostream>
#include<bits/stdc++.h>
#define MAXN 100
#define NAME_MAX
using namespace std;
const int PNumber=5;
const int SNumber=3;
char Source[PNumber];
int Request[SNumber];
int Available[SNumber]={3,3,2};
int MAX[PNumber][SNumber]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
int Allocation[PNumber][SNumber]={{0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2}};
int Need[PNumber][SNumber]={{7,4,3},{1,2,2},{6,0,0},{0,1,1},{4,3,1}};
int OP[PNumber][SNumber];
//int Over[PNumber];
bool judgement(int n){
int flag=0;
for(int j=0; j<SNumber; j++)
if(Need[n][j]==0) flag++;
if(flag==SNumber)return false;
return true;
}
void initialize(){
int i;
for(i=0; i<PNumber; i++)
if(!judgement(i)){
for(int j=0; j<SNumber; j++) Available[j]+=MAX[i][j];
cout<<"进程P"<<i+1<<"所需的资源全部满足,此进程运行完毕!"<<endl;
}
cout<<"此刻进程中存在的进程:"<<endl;
for(i=0; i<PNumber; i++)
if(judgement(i)) cout<<"P"<<i+1<<'\t';
cout<<endl<<"此刻系统可利用的资源(单位:个):"<<endl;
for(i=0; i<SNumber; i++)
printf("%c\t",'A'+i);
cout<<endl;
for(i=0; i<SNumber; i++)
cout<<Available[i]<<'\t';
cout<<endl<<"此刻各进程已占有资源如下(单位:个):"<<endl;
for(i=0; i<SNumber; i++)
printf("\t%c",'A'+i);
cout<<endl;
for(i=0; i<PNumber; i++)
if(judgement(i)){
cout<<"P"<<i+1<<'\t';
for(int j=0; j<SNumber; j++)
cout<<MAX[i][j]-Need[i][j]<<'\t';
cout<<endl;
}
cout<<"各进程运行完毕还需各资源如下(单位:个):"<<endl;
for(i=0; i<SNumber; i++)
printf("\t%c",'A'+i);
cout<<endl;
for(i=0; i<PNumber; i++)
if(judgement(i)){
cout<<"P"<<i+1<<'\t';
for(int j=0; j<SNumber; j++)
cout<<Need[i][j]<<'\t';
cout<<endl;
}
}
void systemstatus(){
}
int security(int n){
int Work[SNumber],i;
bool Finish[PNumber];
for(i=0; i<PNumber; i++)
Finish[i]=false;
for(i=0; i<SNumber; i++)
Work[i]=Available[i];
for(i=0; i<PNumber; i++){
int flag=1;
for(int j=0; j<SNumber; j++)
if(!(Need[i][j]<=Work[j])) flag=0;
if(!Finish[i]&&flag){
for(int j=0; j<SNumber; j++)
Work[j]+=Allocation[i][j];
Finish[i]=true;
//cout<<i<<endl;
i=-1;
continue;
}
}
int flag=1;
for(i=0; i<PNumber; i++)
if(!Finish[i]) flag=0;
if(flag==1){
//
}else{
cout<<"不能满足申请,此进程挂起,原因为:"<<endl;
cout<<"若满足申请,系统将进入不安全状态,可能导致死锁!"<<endl;
return 0;
}
return 1;
}
void banker(int n){
for(int i=0; i<SNumber; i++)
if(!(Request[i]<=Need[n][i])){
cout<<"不能满足申请,此进程挂起,原因为:"<<endl;
cout<<"申请的资源中某种资源大于其声明的需求量!"<<endl;
return;
}
for(int i=0; i<SNumber; i++)
if(!(Request[i]<=Available[i])){
cout<<"不能满足申请,此进程挂起,原因为:"<<endl;
cout<<"申请的资源大于系统可提供的资源量,P"<<n+1<<"需等待"<<endl;
return;
}
for(int i=0; i<SNumber; i++){
Available[i]-=Request[i];
Allocation[n][i]+=Request[i];
Need[n][i]-=Request[i];
}
if(security(n)==1){
cout<<"可以满足申请,";
initialize();
}else{
for(int i=0; i<SNumber; i++){
Available[i]+=Request[i];
Allocation[n][i]-=Request[i];
Need[n][i]+=Request[i];
}
}
}
int main(){
initialize();
int n,i;
while(1){
cout<<"输入发出请求的进程(输入‘0’退出系统):";
cin>>n;
if(n==0) break;
cout<<"此进程申请个资源数目:"<<endl;
for(i=0; i<SNumber; i++){
printf("%c",'A'+i);
cout<<"资源:";
cin>>Request[i];
}
banker(n-1);
}
}
【运行结果】
【结果分析】
第一次:P4请求资源,P4发出请求向量(0,1,0),按银行家算法进行检查
- Request(0,1,0)<=Need(0,1,1,)
- Request(0,1,0)<=Availabele(3,2,2)
- 系统先假定为P4分配资源,并修改相关值
- 利用安全性算法检查此是系统是否安全
同理第二次、第三次可以判断。
在最后一次中,P2请求资源,P4发出请求向量(1,2,2),可以满足申请,并且P2所需的资源全部满足,运行完毕后会释放其占有资源,此时系统的可用资源为{5,2,2}。