使用c语言实现的银行家检测算法,以及对进程资源的分配模拟
目录
1.数据结构
int Allocation[1000][1000] | 分配出去的资源的临接矩阵(行号表示进程编号,列好表示资源编号,值表示分配数量) |
int Need[1000][1000] | 请求资源的临接矩阵(行号表示进程编号,列号表示资源编号,值表示请求数量) |
int Available[1000] | 当前剩余的资源数组,索引号表示资源编号 |
bool Finish[1000] | 已完成分配的进程矩阵,索引号表示进程编号 |
2.变量说明
NP | int | 进程数量 |
NR | int | 资源数量 |
p | int | 遍历到的进程编号 |
r | int | 遍历到的资源编号 |
cnt | int | 未配置的进程数量 |
safe | bool | 是否为安全状态 |
3.函数和功能
loadData() | 加载数据(Allocation、Need、Available) |
printMsg() | 打印当前状态(Allocation、Need、Available) |
banker() | 使用银行家算法检测状态 |
run() | 进行模拟仿真 |
4.流程图
banker方法:
run方法:
5.运行效果:
当前处于安全状态:
分配资源:
分配的不合理,系统进入不安全状态
6.源代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
int Allocation[1000][1000];
int Need[1000][1000];
int Available[1000];
bool Finish[1000];//是否完成分配
int NP;//进程数
int NR;//资源种类数
void loadData(){//加载数据
NP=5;
NR=4;
int allocation[5][4]={{0,0,3,2},{1,0,0,0},{1,3,5,4},{0,3,3,2},{0,0,1,4}};
int need[5][4]={{0,0,1,2},{1,7,5,0},{2,3,5,6},{0,6,5,2},{0,6,5,6}};
int available[4]={1,6,2,2};
for(int p=0;p<NP;p++){
for(int r=0;r<NR;r++){
Allocation[p][r]=allocation[p][r];
Need[p][r]=need[p][r];
}
}
for(int r=0;r<NR;r++)Available[r]=available[r];
}
void printMsg(){//打印函数
printf("--------------------------------\n");
printf("Allocation:\n");
printf("\t R ");
for(int r=0;r<NR;r++)printf("%-4d",r);
printf("\n\tP |");
for(int r=0;r<NR;r++)printf("----");
printf("\n");
for(int p=0;p<NP;p++){
printf("\t%-3d|",p);
for(int r=0;r<NR;r++){
printf("%-4d",Allocation[p][r]);
}printf("\n");
}
printf("Need:\n");
printf("\t R ");
for(int r=0;r<NR;r++)printf("%-4d",r);
printf("\n\tP |");
for(int r=0;r<NR;r++)printf("----");
printf("\n");
for(int p=0;p<NP;p++){
printf("\t%-3d|",p);
for(int r=0;r<NR;r++){
printf("%-4d",Need[p][r]);
}printf("\n");
}
printf("Available:\n\t");
for(int r=0;r<NR;r++)printf("%-3d",Available[r]);
printf("\n\n");
}
bool banker(){//银行家算法
vector<int> safe_seq;
int cnt;
/*
在执行银行家算法检测系统状态时会修改Finish数组和Available数组,
对后面的操作由影响,所以在算法中使用临时数组进行检测修改
*/
bool finish[1000];//临时数组
memcpy(finish,Finish,NP*sizeof(int));
int available_tmp[1000];//临时数组
memcpy(available_tmp,Available,NR*sizeof(int));
//为分配完成的进程计数
for(int p=0;p<NP;p++)cnt+=!finish[p];
//默认处于安全状态
bool safe=1;
while(cnt>0&&safe){
int p;
//依次遍历所有进程,看是否能分配资源
for(p=0;p<NP;p++){
if(!finish[p]){//该进程未被选中
int r;
for(r=0;r<NR;r++){
if(Need[p][r]>available_tmp[r]){//该进程的请求大于剩余
break;
}
}
if(r==NR){//该进程的请求能满足
for(r=0;r<NR;r++){
available_tmp[r]+=Allocation[p][r];//归还资源
}
safe_seq.push_back(p);
finish[p]=1;//已选中该进程
cnt--;//取出当前进程
break;//重新开始下一轮检测
}
}
}
if(p==NP){//无法为任何进程分配资源
safe=0;
}
}
if(!safe)cout<<"unsafe!!!"<<endl<<endl;
else{
cout<<"safe sequence:";
for(int i=0;i<safe_seq.size();i++)cout<<safe_seq[i]<<' ';
cout<<endl<<endl;
}
return safe;
}
void run(){//模拟仿真
int cnt=NP;
int req[1000];
while(cnt>0){
printMsg();
if(!banker())break;//系统进入不安全状态->退出程序
int p;
printf("输入要分配资源的进程编号:");
scanf("%d",&p);
if(p==-1)break;//输入-1,退出程序
if(!Finish[p]){//该进程为待分配资源的进程
bool flag=0;
printf("资源数量(0-%d):",NR);
for(int r=0;r<NR;r++){
scanf("%d",&req[r]);
if(req[r]>Need[p][r])flag=1;
}
if(flag){
printf("请求不合理!!!\n");
continue;
}
int r;
for(r=0;r<NR;r++){
if(req[r]>Available[r]){//该进程的请求大于剩余
break;
}
}
if(r==NR){//该进程的请求能满足
int finish=0;//是否完成分配
for(r=0;r<NR;r++){
Need[p][r]-=req[r];
if(Need[p][r]==0)finish++;
Available[r]-=req[r];
Allocation[p][r]+=req[r];
}
if(finish==NR){//已分配所以资源
Finish[p]=1;//选中该进程
for(r=0;r<NR;r++){
Available[r]+=Allocation[p][r];//归还资源
Allocation[p][r]=0;//持有量值零
}
cnt--;//取出当前进程
}
}else{//该请求无法满足
printf("无法执行分配!!!\n");
}
}else{//进程为已分配完毕的进程
printf("已分配完毕!!!\n");
}
}
if(cnt==0){
printMsg();
printf("finish!!!\n");
}
}
int main(){
loadData();
//banker();
run();
return 0;
}