#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <iomanip>
using namespace std;
//测试数据
//请输入参与的进程数量:4
//请输入参与的资源数量:3
//请输入系统中A资源的数量:9
//请输入系统中B资源的数量:3
//请输入系统中C资源的数量:6
//请输入各进程对各资源的最大需求量:
//3 2 2 6 1 3 3 1 4 4 2 2
//请输入各进程当前已分得各资源的数量:
//1 0 0 5 1 1 2 1 1 0 0 2
int n=100; // 进程数
int m=100; // 资源种类数
int Available[100]={0}; // 可用资源
int Max[100][100]={0}; // 最大需求
int Allocation[100][100]={0}; // 已分得资源
int Need[100][100]={0}; // 需求矩阵
int Work[100]={0}; // 工作向量
bool Finish[100]={0}; // 是否满足
int Request[100]={0}; // 请求资源
char Name[100]={0}; // 资源名称 eg:A B C ...
int P=0; // 请求资源的进程
void init();
bool safeCheck(bool flag);
void printTable();
void recoverSafe();
void bankerMethod();
// 初始化进程和资源
void init()
{
cout << "请输入参与的进程数量:";
cin >> n;
cout << "请输入参与的资源数量:";
cin >> m;
for(int i=0;i<26;i++)
{
Name[i]=i+65;
}
for(int j=0;j<m;j++)
{
//cout << "请输入第" << i+1 << "个资源的名称:";
//cin >> Name[i];
cout << "请输入系统中" << Name[j] << "资源的数量:";
cin >> Available[j];
}
cout << "请输入各进程对各资源的最大需求量:" << endl;
for(int k=0;k<n;k++)
for(int l=0;l<m;l++)
cin >> Max[k][l];
cout << "请输入各进程当前已分得各资源的数量:" << endl;
for(int i1=0;i1<n;i1++)
for(int j=0;j<m;j++)
cin >> Allocation[i1][j];
for(int i2=0;i2<n;i2++)
for(int j=0;j<m;j++)
Need[i2][j]=Max[i2][j]-Allocation[i2][j];
// 初始化Available
for(int i3=0;i3<n;i3++)
for(int j=0;j<m;j++)
Available[j]=Available[j]-Allocation[i3][j];
// 初始化Work
recoverSafe();
}
// 安全性检查
bool safeCheck(bool flag)
{
//cout << "---DATA---|" << "----Work---|" << "----Need---|" << "-Allocation|" << "Work+Allocation|" << "--Finish--|" << endl;
//cout << "-RESOURCE-|" << "--A--B--C--|" << "--A--B--C--|" << "--A--B--C--|" << "---A---B---C---|" << endl;
cout << "---DATA---|" << setfill(' ') << setw(3*m+2) << "Work" << "|" << setw(3*m+2) << "Need" << "|" << setw(3*m+2) << "Allocation" << "|" << setw(3*m+2) << "Work+Allo" << "|" << "Finish|" << endl;
cout << "-RESOURCE-|";
for(int i=0;i<m;i++)
cout << "--" << Name[i];
cout << "--|";
for(int i1=0;i1<m;i1++)
cout << "--" << Name[i1];
cout << "--|";
for(int i2=0;i2<m;i2++)
cout << "--" << Name[i2];
cout << "--|";
for(int i3=0;i3<m;i3++)
cout << "--" << Name[i3];
cout << "--|" << endl;
number0:
for(int i4=0;i4<n;i4++)
{
int count=0;
for(int j=0;j<m;j++)
{
if(!Finish[i4] && Need[i4][j]<=Work[j])
{
count++;
}
if(count==m)
{
cout << "----P" << i4 << "----|";
for(int k=0;k<m;k++)
cout << "-" << setw(2) << Work[k];
cout << "--|";
for(int k1=0;k1<m;k1++)
cout << "-" << setw(2) << Need[i4][k1];
cout << "--|";
for(int k2=0;k2<m;k2++)
cout << "-" << setw(2) << Allocation[i4][k2];
cout << "--|";
for(int k3=0;k3<m;k3++)
{
Work[k3]=Work[k3]+Allocation[i4][k3];
}
Finish[i4]=true;
for(int k4=0;k4<m;k4++)
cout << "-" << setw(2) << Work[k4];
cout << "--|";
cout << "--" << Finish[i4] << "--|";
cout << endl;
goto number0;
}
}
}
for(int i5=0;i5<n;i5++)
{
if(!Finish[i5])
{
flag=false;
break;
}
}
if(flag)
{
cout << "**系统处于安全状态**" << endl;
return true;
}
else
{
cout << "**系统处于不安全状态**" << endl;
return false;
}
}
// 打印进程请求后资源分配表
void printTable()
{
cout << "---DATA---|" << setw(4*m) << "Max" << "|" << setw(4*m) << "Allocation" << "|" << setw(4*m) << "Need" << "|" << setw(4*m) << "Available" << "|" << endl;
cout << "-RESOURCE-|";
for(int i=0;i<m;i++)
cout << "-" << Name[i] << "--";
cout << "|";
for(int i1=0;i1<m;i1++)
cout << "-" << Name[i1] << "--";
cout << "|";
for(int i2=0;i2<m;i2++)
cout << "-" << Name[i2] << "--";
cout << "|";
for(int i3=0;i3<m;i3++)
cout << "-" << Name[i3] << "--";
cout << "|" << endl;
for(int i4=0;i4<n;i4++)
{
cout << "---P" << i4 << "-----|";
for(int j=0;j<m;j++)
{
cout << "-" << setfill('0') << setw(2) << Max[i4][j] << "-";
}
cout << "|";
for(int j1=0;j1<m;j1++)
{
cout << "-" << setfill('0') << setw(2) << Allocation[i4][j1] << "-";
}
cout << "|";
for(int j2=0;j2<m;j2++)
{
cout << "-" << setfill('0') << setw(2) << Need[i4][j2] << "-";
}
cout << "|";
if(i4==0)
{
for(int j3=0;j3<m;j3++)
cout << "-" << setfill('0') << setw(2) << Available[j3] << "-";
cout << "|";
}
cout << endl;
}
}
// 安全性检查后,恢复Work向量和Finish向量
void recoverSafe()
{
// 恢复Work
for(int i=0;i<m;i++)
Work[i]=Available[i];
for(int i1=0;i1<n;i1++)
Finish[i1]=false;
}
// 银行家算法
void bankerMethod()
{
// 客户端提示
cout << "请输入需要请求资源的进程编号(int型):" << endl;
for(int i=0;i<n;i++)
{
cout << setfill(' ') << setw(3) << "P" << i << ": " << i << endl;
}
// 检查输入合法性
int tmpP=-1;
bool flagP=false;
while(!flagP){
cout << "进程编号:";
scanf("%d",&tmpP);
if(tmpP<0 || tmpP>=n){
cout << "此进程不存在,请重新输入!" << endl;
flagP=false;
//防止不断循环
while (getchar()!='\n');
} else {
P=tmpP;
flagP=true;
}
}
// 确认请求资源Request
for(int i1=0;i1<m;i1++)
{
cout << "请输入进程P" << P << "请求的" << Name[i1] << "资源的数量:";
cin >> Request[i1];
}
// 1.判断进程请求数量是否小于需求最大数量
bool flag=true;
int countRN=0;
for(int i2=0;i2<m;i2++)
{
if(Request[i2]<=Need[P][i2])
countRN++;
if(countRN==m)
flag=true;
else
flag=false;
}
if(flag)
{
// 2.判断进程请求数量是否小于系统可用数量
int countRA=0;
for(int i=0;i<m;i++)
{
if(Request[i]<=Available[i])
countRA++;
if(countRA==m)
flag=true;
else
flag=false;
}
if(flag)
{
// 3.系统试探着把资源分配给进程
for(int i=0;i<m;i++){
Available[i]=Available[i]-Request[i];
Allocation[P][i]=Allocation[P][i]+Request[i];
Need[P][i]=Need[P][i]-Request[i];
Work[i]=Work[i]-Request[i];
}
// T0时刻的资源分配表
cout << "-----------------------为P" << P << "分配资源后的资源分配表------------------------" << endl;
printTable();
// 4.安全性算法
cout << "------------------------P" << P << "申请资源时的安全性检查-------------------------" << endl;
flag=safeCheck(flag);
// 如果安全性检查不通过,则回收进程请求的资源
if(!flag)
{
for(int i=0;i<m;i++){
Available[i]=Available[i]+Request[i];
Allocation[P][i]=Allocation[P][i]-Request[i];
Need[P][i]=Need[P][i]+Request[i];
Work[i]=Work[i]+Request[i];
}
}
recoverSafe();
}
else
cout << "**系统中没有足够资源**" << endl;
}
else
cout << "**请求已超出进程P" << P << "需求最大值**" << endl;
}
int main(int argc, char* argv[])
{
// 初始化进程和资源
cout << "********************************初始化进程和资源********************************" << endl;
init();
cout << "**********************************初始化已完成**********************************" << endl;
// T0时刻的资源分配表
cout << "---------------------------T0时刻的资源分配表----------------------------" << endl;
printTable();
// T0时刻的安全性检查
cout << "---------------------------T0时刻的安全性检查----------------------------" << endl;
// 恢复安全性检查向量
recoverSafe();
// 银行家算法
while(true)
{
cout << "是否要继续请求资源(y/n):" << endl;
char ynRequest;
cin >> ynRequest;
if(ynRequest=='n' || ynRequest=='N')
break;
bankerMethod();
}
return 0;
}
银行家算法中使用到的数据结构
- 可利用资源数组(Available)
- 进程最大需求矩阵(Max)
- 分配矩阵(Allocation)
- 需求矩阵(Need)
总体步骤
- 如果request < need 则转向步骤2,否则出错,因为进程所申请的资源数已经超过了它所需要的资源数。
- 如果request < available 则转向步骤3,否则,表示系统中没有足够的资源满足进程pi的申请,pi必须等待。
- 尝试把系统的资源分配给pi,并修改下面数据结构中的数值
Available[i]=Available[i]-Request[i];
Allocation[P][i]=Allocation[P][i]+Request[i];
Need[P][i]=Need[P][i]-Request[i];
- 系统执行安全性检测算法,检查此次尝试分配后,系统是否处于安全状态。如果安全,则正是把资源分配给进程pi,完成本次分配;否则将尝试是分配作废,系统恢复原来资源分配的状态,让pi等待。
安全性检查步骤
- .设两个数组work 和 finish,其中
work表示系统可提供给进程继续运行的各类资源的空闲数目,它包含m个元素,执行安全算法开始时,work[i]= available[i]。
finish表示系统是否有足够的资源分配给进程,使之运行完成,开始时finish[i]=false;当有足够资源分配给进程pi时,使finish[i]=true。
- .从进程集合中找出资源满足下述条件的进程:
finish[i]=false;Need[i] < work;
如果找到,则执行步骤(3),否则执行步骤(4)
- .当进程pi获得资源后,可顺利执行知道完毕,并释放出分配给它的资源,所以应执行:
Work[i] = Work[i] + Allocation[i];
Finish[i] = true;
goto Step 2;
- .如果所有进程的Finish都为True,则表示系统处于安全状态;否则表示系统处于不安全状态。
程序执行结果
********************************初始化进程和资源********************************
请输入参与的进程数量:4
请输入参与的资源数量:3
请输入系统中A资源的数量:9
请输入系统中B资源的数量:3
请输入系统中C资源的数量:6
请输入各进程对各资源的最大需求量:
3 2 2 6 1 3 3 1 4 4 2 2
请输入各进程当前已分得各资源的数量:
1 0 0 5 1 1 2 1 1 0 0 2
**********************************初始化已完成**********************************
---------------------------T0时刻的资源分配表----------------------------
---DATA---| Max| Allocation| Need| Available|
-RESOURCE-|-A---B---C--|-A---B---C--|-A---B---C--|-A---B---C--|
---P0-----|-03--02--02-|-01--00--00-|-02--02--02-|-01--01--02-|
---P1-----|-06--01--03-|-05--01--01-|-01--00--02-|
---P2-----|-03--01--04-|-02--01--01-|-01--00--03-|
---P3-----|-04--02--02-|-00--00--02-|-04--02--00-|
---------------------------T0时刻的安全性检查----------------------------
是否要继续请求资源(y/n):
y
请输入需要请求资源的进程编号(int型):
P0: 0
P1: 1
P2: 2
P3: 3
进程编号:3
请输入进程P3请求的A资源的数量:1
请输入进程P3请求的B资源的数量:1
请输入进程P3请求的C资源的数量:0
-----------------------为P3分配资源后的资源分配表------------------------
---DATA---| Max| Allocation| Need| Available|
-RESOURCE-|-A---B---C--|-A---B---C--|-A---B---C--|-A---B---C--|
---P0-----|-03--02--02-|-01--00--00-|-02--02--02-|-00--00--02-|
---P1-----|-06--01--03-|-05--01--01-|-01--00--02-|
---P2-----|-03--01--04-|-02--01--01-|-01--00--03-|
---P3-----|-04--02--02-|-01--01--02-|-03--01--00-|
------------------------P3申请资源时的安全性检查-------------------------
---DATA---| Work| Need| Allocation| Work+Allo|Finish|
-RESOURCE-|--A--B--C--|--A--B--C--|--A--B--C--|--A--B--C--|
**系统处于不安全状态**
是否要继续请求资源(y/n):
y
请输入需要请求资源的进程编号(int型):
P0: 0
P1: 1
P2: 2
P3: 3
进程编号:1
请输入进程P1请求的A资源的数量:1
请输入进程P1请求的B资源的数量:0
请输入进程P1请求的C资源的数量:1
-----------------------为P1分配资源后的资源分配表------------------------
---DATA---| Max| Allocation| Need| Available|
-RESOURCE-|-A---B---C--|-A---B---C--|-A---B---C--|-A---B---C--|
---P0-----|-03--02--02-|-01--00--00-|-02--02--02-|-00--01--01-|
---P1-----|-06--01--03-|-06--01--02-|-00--00--01-|
---P2-----|-03--01--04-|-02--01--01-|-01--00--03-|
---P3-----|-04--02--02-|-00--00--02-|-04--02--00-|
------------------------P1申请资源时的安全性检查-------------------------
---DATA---| Work| Need| Allocation| Work+Allo|Finish|
-RESOURCE-|--A--B--C--|--A--B--C--|--A--B--C--|--A--B--C--|
----P1----|- 0- 1- 1--|- 0- 0- 1--|- 6- 1- 2--|- 6- 2- 3--|--1--|
----P0----|- 6- 2- 3--|- 2- 2- 2--|- 1- 0- 0--|- 7- 2- 3--|--1--|
----P2----|- 7- 2- 3--|- 1- 0- 3--|- 2- 1- 1--|- 9- 3- 4--|--1--|
----P3----|- 9- 3- 4--|- 4- 2- 0--|- 0- 0- 2--|- 9- 3- 6--|--1--|
**系统处于安全状态**
是否要继续请求资源(y/n):