#include <iostream>
#include <string>
#define M 3 //资源的种类数
#define N 5 //进程的个数
char safeSeries [N];
using namespace std;
void output(int iMax[N][M], int iAllocation[N][M], int iNeed[N][M], int iAvailable[M], char cName[N]); // 输出打印
bool safety(int iAllocation[N][M], int iNeed[N][M], const int iAvailable[M], const char cName[N]); // 安全性算法
bool banker(int iAllocation[N][M], int iNeed[N][M], int iAvailable[M], char cName[N]); // 银行家算法
int main()
{
int i, j;
//当前可用每类资源的资源数
int iAvailable[M] = { 3,3,2 };
//系统中N个进程中的每一个进程对M类资源的最大需求
int iMax[N][M] = { {7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3} };
//iNeed[N][M]每一个进程尚需的各类资源数
//iAllocation[N][M]为系统中每一类资源当前已分配给每一进程的资源数
int iNeed[N][M], iAllocation[N][M] = { {0,1,0},{2,0,0},{3,0,2},{2,1,1},{0,0,2} };
//进程名
char cName[N] = { 'a','b','c','d','e' };
bool bExitFlag = true; //退出标记
char ch; //接收选择是否继续提出申请时传进来的值
bool bSafe; //存放安全与否的标志
//计算iNeed[N][M]的值
for (i = 0; i < N; i++)
for (j = 0; j < M; j++)
iNeed[i][j] = iMax[i][j] - iAllocation[i][j];
output(iMax, iAllocation, iNeed, iAvailable, cName);
bSafe = safety(iAllocation, iNeed, iAvailable, cName);
if(bSafe)
{
cout<<"当前出于安全状态";
cout<<"安全序列为:"<<endl;
for(int i = 0;i < N;++i)
{
if(i == N-1)
cout<<safeSeries[i];
else
cout<<safeSeries[i]<<"-->";
}
cout<<endl;
}
else
cout<<"当前不是安全状态";
//是否继续
while (bExitFlag)
{
cout << "\n" << "继续提出申请?\ny为是;n为否。\n";
cin >> ch;
switch (ch)
{
case 'y':
//cout<<"调用银行家算法";
bSafe = banker(iAllocation, iNeed, iAvailable, cName);
if (bSafe) //安全,则输出变化后的数据
output(iMax, iAllocation, iNeed, iAvailable, cName);
break;
case 'n':
cout << "退出\n";
bExitFlag = false;
break;
default:
cout << "输入有误,请重新输入:\n";
}
}
return 0;
}
//输出
void output(int iMax[N][M],int iAllocation[N][M],int iNeed[N][M],int iAvailable[M],char cName[N])
{
int i,j;
cout<<"\n\t Max \tAllocation\t Need \t Available"<<endl;
cout<<"\tA B C\tA B C\tA B C\t A B C"<<endl;
for(i=0;i<N;i++)
{
cout<<cName[i]<<"\t";
for(j=0;j<M;j++)
cout<<iMax[i][j]<<" ";
cout<<"\t";
for(j=0;j<M;j++)
cout<<iAllocation[i][j]<<" ";
cout<<"\t";
for(j=0;j<M;j++)
cout<<iNeed[i][j]<<" ";
cout<<"\t";
cout<<" ";
//Available只需要输出一次
if (i==0)
for(j=0;j<M;j++)
cout<<iAvailable[j]<<" ";
cout<<endl;
}
}
//安全性算法,进行安全性检查
bool safety(int iAllocation[N][M], int iNeed[N][M], const int iAvailable[M],const char cName[N])
{
// 工作向量Work表示系统目前可提供的资源,含有M个元素,安全性算法开始时Work等于iAvailable
int Work[M];
for (int i = 0; i < M; ++i) Work[i] = iAvailable[i];
// 表示第i个进程是否已经分配资源,初始时全为false
bool Finish[N];
for (auto & finish : Finish) finish = false;
// safeFlag:是否有安全序列的标记 fitProFlag: 是否为合适进程的标记
bool safeFlag = true, fitProFlag = true;
int index,i;
for(index = 0;index < N; ++index)
{
for(i = 0;i < N;++i)
{
// 查找符合条件的进程(没有分配资源,且目前对各类资源的需求均不大于目前能提供的资源)
if(Finish[i]) continue; // 进程i已经可以分配过资源,就跳过
fitProFlag = true; // 将符合要求的进程标志标记为true
for(int j = 0;j < M;++j)
{
if(iNeed[i][j] > Work[j])
{
fitProFlag = false; // 出现进程i目前对某一类资源的需求大于目前能提供的资源则将标志记为false,表示进程i不是符合要求的进程,跳出
break;
}
}
// 当进程i为合适的进程时才执行
if(fitProFlag)
{
safeSeries[index] = cName[i]; // 讲进程填入安全序列
Finish[i] = true; // 标记能够为其分配到资源
for(int k = 0;k<M;++k) // 为进程i分配资源后,进程i执行结束,将以前进程i占用的资源回收
Work[k] += iAllocation[i][k];
break; // 结束内层循环,进行下一轮的从前往后的查找
}
}
if(i == N)
safeFlag = false;
}
return safeFlag;
}
bool banker(int iAllocation[N][M], int iNeed[N][M], int iAvailable[M], char cName[N])
{
// 1.信息的输入
int proIndex; // 申请资源的进程索引
char proName; // 申请资源的进程名称
int request[M]; // proName申请资源的信息
bool flag = true; // 用于检测申请的资源数量是否符合要求
cout<<"输入申请资源的进程:"<<endl;
cin>>proName;
for(int i = 0;i< N;++i) // 查找输入的进程名字对应的下标
{
if(cName[i]==proName)
{
proIndex = i;
break;
}
}
cout<<"输入进程对各类资源申请的数量:"<<endl;
for(int & re : request)
{
cin>>re;
}
// 2.检测申请的资源数量是否超过现在需要的资源数量
for(int j = 0; j < M ; ++j)
{
if(request[j] > iNeed[proIndex][j])
{
flag = false;
break;
}
}
if(!flag)
{
cout<<"资源申请失败,该进程申请的资源超过需要的资源数量"<<endl;
return false;
}
// 3.检测申请的资源数量是否超过现在能够提供的资源
flag = true; // flag为true表示有足够资源,为false表示申请的资源数量熬过
for(int j = 0 ; j < M ; ++j)
{
if(request[j] > iAvailable[j])
{
flag = false;
break;
}
}
if(!flag) {
cout << "资源申请失败,该进程申请的资源数量超过当前系统能提供的资源" << endl;
return false;
}
// 4.假定分配资源,得到新的状态
for(int j = 0;j < M;++j)
{
iAvailable[j] -= request[j]; // 系统可提供资源更新
iAllocation[proIndex][j] += request[j]; // 已分配资源矩阵更新
iNeed[proIndex][j] -= request[j]; // 更新proName进程还需要的资源
}
// 5.调用安全性算法,检测假定分配后是否存在安全序列。如果存在就提交并打印安全序列,不存在就回滚并给出说明
if(safety(iAllocation,iNeed,iAvailable,cName))
{
cout<<"资源分配成功,安全序列为:"<<endl;
for(int i = 0;i < N;++i)
{
if(i == N-1)
cout<<safeSeries[i];
else
cout<<safeSeries[i]<<"-->";
}
cout<<endl;
// 当某个进程提出申请资源后,该进程的最大的资源需求量iMax[i][0……M]等于已经分配的资源量iAllocation[i][0……M],即该进程当前对各类资源的需求量iNeed[i][0……M]均为0,
// 进程执行结束。将该进程占用的资源回收。即修改当前系统可提供的资源iAvailable[0……M]增加上回收的该进程原先占用的资源iAllocation[0……M]。原先分配给该进程的资源iAllocation[0……M]置为0
for(int i = 0;i < N;++i)
{
int j;
for(j = 0;j < M;++j)
{
if(iNeed[i][j] != 0)
break;
}
if(j == M)
{
for(j = 0;j < M;++j)
{
iAvailable[j] += iAllocation[i][j];
iAllocation[i][j] = 0;
}
}
}
}
else
{
cout<<"资源分配失败"<<endl;
for(int j = 0;j < M;++j)
{
iAvailable[j] += request[j]; // 系统可提供资源回滚
iAllocation[proIndex][j] -= request[j]; // 已分配资源矩阵回滚
iNeed[proIndex][j] += request[j]; // 回滚proName进程还需要的资源
}
}
return true;
}
银行家算法
最新推荐文章于 2023-10-06 15:54:51 发布