【实验原理】
一、安全状态
指系统能按照某种顺序如<P1,P2,…,Pn>(称为<P1,P2,…,Pn>序列为安全序列),为每个进程分配所需的资源,直至最大需求,使得每个进程都能顺利完成。
二、银行家算法
假设在进程并发执行时进程i提出请求j类资源k个后,表示为Requesti[j]=k。系统按下述步骤进行安全检查:
(1)如果Requesti≤Needi则继续以下检查,否则显示需求申请超出最大需求值的错误。
(2)如果Requesti≤Available则继续以下检查,否则显示系统无足够资源,Pi阻塞等待。
(3)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:
Available[j]∶=Available[j]-Requesti[j];
Allocation[i,j]∶=Allocation[i,j]+Requesti[j];
Need[i,j]∶=Need[i,j]-Requesti[j];
(4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则, 将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
三、安全性算法
(1)设置两个向量:
① 工作向量Work: 它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work∶=Available;
② Finish: 它表示系统是否有足够的资源分配给进程,使之运行完成。开始时先做Finish[i]∶=false; 当有足够资源分配给进程时, 再令Finish[i]∶=true。
(2)从进程集合中找到一个能满足下述条件的进程:
① Finish[i]=false;
② Need[i,j]≤Work[j]; 若找到, 执行步骤(3), 否则,执行步骤(4)。
(3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
-
- Work[j]∶=Work[i]+Allocation[i,j];
- Finish[i]∶=true;
- go to step 2;
(4)如果所有进程的Finish[i]=true都满足, 则表示系统处于安全状态;否则,系统处于不安全状态。
下面是运行结果与代码:
#include <iostream>
#include <string.h>
using namespace std;
#define M 3 //资源种类数
#define N 5 //进程个数
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],int iAvailable[M],char cName[N]);
bool banker(int iAllocation[N][M],int iNeed[N][M],int iAvailable[M],char cName[N]);
//整齐输出
void output(int iMax[N][M], int iAllocation[N][M], int iNeed[N][M], int iAvailable[M], char cName[N])
{
cout<<"\t Max \tAllocation\t Need \t Available"<<endl;
cout<<"\tA B C\tA B C\tA B C\t A B C"<<endl;
for (int i = 0; i < N; i++)
{
cout << cName[i] << '\t';
for(int j = 0; j < M; j++)
{
cout << iMax[i][j] << " ";
}
cout << '\t';
for(int j = 0; j < M; j++)
{
cout << iAllocation[i][j] << " ";
}
cout << '\t';
for(int j = 0; j < M; j++)
{
cout << iNeed[i][j] << " ";
}
cout<<"\t";
cout<<" ";
if(i == 0)
{
for(int j = 0; j < M; j++)
{
cout << iAvailable[j] << " ";
}
}
cout << endl;
}
cout << endl;
}
//安全性算法
bool safety(int iAllocation[N][M], int iNeed[N][M],int iAvailable[M],char cName[N])
{
int finishedNum;
int work[M], safeList[N]= {0, 0,0,0,0};
bool finish[N];
//复制available到work
for(int i = 0; i < M; i++)
{
work[i] = iAvailable[i];
}
//初始化全为false
for (int i = 0; i < N; i++)
{
finish[i] = false;
}
// int i, j, m, n;
int i = 0;
int j = 0;
int m = 0;
int n = 0;
while (i < N)
{
if (finish[i] == false)
{
while (j < M && iNeed[i][j] <= work[j])
j++;
if (j == M)
{
for (int k = 0; k < M; k++)
{
work[k] += iAllocation[i][k];
}
finish[i] = true;
safeList[m] = i;
i = -1; m++;
}
}
j = 0;
i ++;
}
for (int p = 0; p < N; p++)
{
if (finish[p] == true)
{
n++;
}
}
finishedNum = n;
if (finishedNum == N)
{
cout << "当前时刻系统的一个安全序列为:" << endl;
for (int i = 0; i < N; i++)
{
if (safeList[i] == 0)
cout << 'a' << " ";
if (safeList[i] == 1)
cout << 'b' << " ";
if (safeList[i] == 2)
cout << 'c' << " ";
if (safeList[i] == 3)
cout << 'd' << " ";
if (safeList[i] == 4)
cout << 'e' << " ";
// cout << safeList[i] << " ";
}
cout << endl;
return true;
}
cout << "\n系统不安全!" << endl;
return false;
}
//银行家算法
bool banker(int iAllocation[N][M],int iNeed[N][M],int iAvailable[M],char cName[N])
{
int request[M];
char reqProcess;
cout << "输入提出资源申请的进程名:" << endl;
cin >> reqProcess ;
// cout << reqProcess - 97 << endl;
cout << "输入申请各类资源的数量:" << endl;
for (int i = 0; i < M; i++)
{
cin >> request[i];
}
int i = 0;
for (int i= 0; i < M; i++)
{
if (request[i] <= iNeed[reqProcess - 97][i])
{
continue;
}
else
{
cout << "ERROR!" << endl;
return false;
}
}
for (int i = 0; i < M; i++)
{
if (request[i] <= iAvailable[i])
{
continue;
}
else
{
cout << "ERROR!" << endl;
return false;
}
}
for (int k = 0; k < M; k++)
{
iAvailable[k] -= request[k];
iAllocation[reqProcess - 97][k] += request[k];
iNeed[reqProcess-97][k] -= request[k];
}
if (safety(iAllocation,iNeed,iAvailable,cName))
{
return true;
}
else
{
for (int k = 0; k < M; k++)
{
iAvailable[k] += request[k];
iAllocation[reqProcess - 97][k] -= request[k];
iNeed[reqProcess-97][k] += request[k];
}
return false;
}
}
int main()
{
//当前可用每类资源的资源数
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]每一个进程尚需的各类资源数
int iNeed[N][M];
//iAllocation[N][M]为系统中每一类资源当前已分配给每一进程的资源数
int iAllocation[N][M]={{0,1,1},{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(int i = 0; i < N; i++)
{
for(int 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);
//是否继续提出申请
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";
}
}
}