1. 先附上源程序(运行程序前请将注释的文件内容创建名为process_info.txt的文件,并放在代码所在目录下)
#include<iostream>
#include<stdio.h>
using namespace std;
typedef int Status;
/*FilePath路径下文件内容(新创建txt文件并更改FilePath路径)
---------------------------------------------
NUM(PROCESS_AND_RESOURCE)
5 3
AVAILABLE
3 3 2
MAX
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
ALLOCATION
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
--------------------------------------------- */
//--------------------------宏定义-----------------------------------------
#define OTHER_ERROR -1 //其他请求请求资源失败的原因(这里没有用到)
#define OVER_NEED 0 //资源需求申请超出最大需求值
#define RES_NOT_ENOUGH 1 //系统无足够资源
#define NOT_SAFE 2 //未通过安全性算法检测
#define OK 3 //通过安全性算法检测,且无其他错误,请求资源成功
//--------------------------函数声明----------------------------------------
void ReadProcessInfo(); //读取进程的所有信息
int SafetyJudge(); //安全性检测算法
int NeedNGWork(int Work[],int row); //用于比较Need[row,j]和Work[j]
Status Request_BankerALG(int Request [],int x); //判断能否请求成功_银行家算法
void Display();//进程信息和当前系统资源状态显示
void Request();//模拟进程申请资源的过程,并检测能否成功申请
void showMenu();//菜单显示
//-----------------------------全局变量--------------------------------------
char FilePath[40]="process_info.txt";
//进程和系统资源信息文件存储位置
int Num_Process; //Num_Process为当前系统的进程数量
int Num_Resource; //Num_Resource为当前系统可提供的资源种类数量
bool *Finish; //用于安全性检测算法中进程能否顺利完成
int *Available,**MAX,**Allocation,**Need,*Work;
int Readed=0; //用于标志是否成功读取文件
int *Sequence; //用于存储安全序列
//---------------------------------------------------------------------------
int main()
{
int select=0;
while(select!=-1)
{
showMenu();
cout<<"----->>请输入要进行的操作...(退出请输入-1)"<<endl;
cin>>select;
switch(select)
{
case 1:
{
int yes=0;
if(Readed)
{
cout<<"--->>是否重新读取进程和系统资源信息?(1-是/0-否)"<<endl;
cin>>yes;
if(yes)
{
ReadProcessInfo();
Readed=1;
cout<<"数据已更新!"<<endl;
}
else cout<<"已选择继续使用原数据..."<<endl;
}
else
{
ReadProcessInfo();
Readed=1;
}
break;
}
case 2:
{
if(!Readed)
cout<<"进程和系统资源信息尚未读取,请执行操作1!"<<endl;
else Display();
break;
}
case 3:
{
if(!Readed)
cout<<"进程和系统资源信息尚未读取,请执行操作1!"<<endl;
else SafetyJudge();
break;
}
case 4:
{
if(!Readed)
cout<<"进程和系统资源信息尚未读取,请执行操作1!"<<endl;
else Request();
break;
}
default:break;
}
}
return 0;
}
int SafetyJudge()//安全性检测算法
{
int i,j,k=0;
Work=new int[Num_Resource];
for(i=0;i<Num_Resource;i++)
Work[i]=Available[i]; //以Available[]作为Work[]的初值
int FALSE=1;
for(i=0;i<Num_Process;i++)
Finish[i]=false;//每调用一次安全性检测算法SafetyJudge,初始化Finish[]为false
while(1)
{
FALSE=1;
for(i=0;i<Num_Process;i++)
{
if(Finish[i]==false&&NeedNGWork(Work,i))//满足条件1和2
{
FALSE=0;
//cout<<i<<" satisfied!"<<endl;
Sequence[k]=i;//记录安全序列
k++;
for(j=0;j<Num_Resource;j++)
{
Work[j]=Work[j]+Allocation[i][j];
Finish[i]=true;
}
}
}
if(FALSE==1)
break;
}
for(i=0;i<Num_Process;i++)
if(Finish[i]==false)
break;
if(i<Num_Process)
{
cout<<"该状态未通过安全性检测"<<endl;
return 0;
}
else
{
cout<<"该状态通过安全性检测,安全序列为:"<<endl;
cout<<"| ";
for(i=0;i<Num_Process;i++)
cout<<"P"<<Sequence[i]<<" ";
cout<<"|"<<endl;
return 1;
} //所有进程都能够完成则返回1,否则返回0
}
int NeedNGWork(int Work[],int row)//用于比较Need[row,j]和Work[j]
{
int *need=new int[Num_Resource];
int i;
for(i=0;i<Num_Resource;i++)
need[i]=Need[row][i];
for(i=0;i<Num_Resource;i++)
if(need[i]>Work[i])
break;
if(i<Num_Resource)
return 0;
else return 1;//Need[row,j]<=Work[j]时,返回1,否则返回0
}
Status Request_BankerALG(int Request[],int x)
{//第x个进程提出资源请求Request[],若申请成功则返回1,否则返回-1
int i,j;
//---------------为初始数组分配空间--------------------------
int *Available_init=new int[Num_Resource];
int **Allocation_init=new int*[Num_Process];
int **Need_init=new int *[Num_Process];
for(i=0;i<Num_Process;i++)
{
Allocation_init[i]=new int[Num_Resource];
Need_init[i]=new int[Num_Resource];
}
//------------------------------------------------------------
for(i=0;i<Num_Resource;i++)
Available_init[i]=Available[i];//保存Available[]原始值,在未通过安全性算法时,可将值恢复为原始值
for(i=0;i<Num_Process;i++)
{
for(j=0;j<Num_Resource;j++)
{
Need_init[i][j]=Need[i][j];//保存Need[][]原始值,在未通过安全性算法时,可将值恢复为原始值
Allocation_init[i][j]=Allocation[i][j];//保存Allocation[][]原始值,在未通过安全性算法时,可将值恢复为原始值
}
}
//-----------------------------------------------------------------------------------------------------------------
for(i=0;i<Num_Resource;i++)
if(Request[i]>Need[x][i])
return OVER_NEED; //资源需求申请超出最大需求值
for(i=0;i<Num_Resource;i++)
if(Request[i]>Available[i])
return RES_NOT_ENOUGH; //系统无足够资源
for(i=0;i<Num_Resource;i++)
{
Available[i]-=Request[i];
Allocation[x][i]+=Request[i];
Need[x][i]-=Request[i];
}
Status Safety=SafetyJudge();
if(Safety)
return OK;
else //未通过安全性算法,恢复为原始值
{
for(i=0;i<Num_Resource;i++)
Available[i]=Available_init[i];//保存Available[]原始值,在未通过安全性算法时,可将值恢复为原始值
for(i=0;i<Num_Process;i++)
{
for(j=0;j<Num_Resource;j++)
{
Need[i][j]=Need_init[i][j];
Allocation[i][j]=Allocation_init[i][j];
}
}
return NOT_SAFE;
}
}
void ReadProcessInfo()//读取进程的所有信息
{
char temps[50];
int i,j;
FILE *fp=fopen(FilePath,"r");
if(fp==NULL)
{
cout<<"文件process_info.txt读取失败!"<<endl;
exit(-1);
}
fscanf(fp,"%s",temps); //吸收提示字符串
fscanf(fp,"%d%d",&Num_Process,&Num_Resource);
fscanf(fp,"%s",temps); //吸收提示字符串
//----------------------------为需要的所有数组分配空间------------------------------------
Available=new int[Num_Resource];
MAX=new int*[Num_Process];
Allocation=new int*[Num_Process];
Need=new int*[Num_Process];
Finish=new bool[Num_Process];//为Finsh[]数组分配空间
Work=new int[Num_Resource];
Sequence=new int[Num_Process];
for(i=0;i<Num_Process;i++)
{
MAX[i]=new int[Num_Resource];
Allocation[i]=new int[Num_Resource];
Need[i]=new int[Num_Resource];
}
//----------------------------初始化所有数组-------------------------------
for(i=0;i<Num_Resource;i++)
fscanf(fp,"%d",&Available[i]);
fscanf(fp,"%s",temps); //吸收提示字符串
for(i=0;i<Num_Process;i++)
for(j=0;j<Num_Resource;j++)
fscanf(fp,"%d",&MAX[i][j]);
fscanf(fp,"%s",temps); //吸收提示字符串
for(i=0;i<Num_Process;i++)
for(j=0;j<Num_Resource;j++)
fscanf(fp,"%d",&Allocation[i][j]);
//-----------------------------计算Need[][]---------------------------------
for(i=0;i<Num_Process;i++)
for(j=0;j<Num_Resource;j++)
Need[i][j]=MAX[i][j]-Allocation[i][j];
//--------------------以Available[]作为Work[]的初值 ------------------------
for(i=0;i<Num_Resource;i++)
Work[i]=Available[i]; //以Available[]作为Work[]的初值
cout<<"进程和系统资源信息读取完成!"<<endl;
fclose(fp);
}
//TODO
void Display()//进程信息和当前系统资源状态显示
{
int i,j;
cout<<"\t-------------------------------"<<endl;
cout<<"\t|当前进程数量为"<<Num_Process<<" |"<<endl;
cout<<"\t|系统当前可用资源种类数量为"<<Num_Resource<<" |"<<endl;
cout<<"\t-------------------------------"<<endl;
cout<<"---------------进程信息和当前系统资源状态---------------"<<endl;
cout<<"进程\t"<<" Max "<<"Allocation\t"<<"Need\t"<<"Available"<<endl;
for(i=0;i<Num_Process;i++)
{
cout<<"P"<<i<<"\t";
for(j=0;j<Num_Resource;j++)
cout<<MAX[i][j]<<" ";
cout<<"\t";
for(j=0;j<Num_Resource;j++)
cout<<Allocation[i][j]<<" ";
cout<<"\t\t";
for(j=0;j<Num_Resource;j++)
cout<<Need[i][j]<<" ";
cout<<"\t";
if(i==0)
for(j=0;j<Num_Resource;j++)
cout<<Available[j]<<" ";
cout<<endl;
}
cout<<"--------------------------------------------------------"<<endl;
}
void Request()//模拟进程申请资源的过程,并检测能否成功申请
{
int i;
int x;//申请资源的进程编号
int *request=new int[Num_Resource];
cout<<"请输入申请资源的进程编号"<<endl;
cin>>x;
cout<<"--->>请输入进程"<<x<<"申请"<<Num_Resource<<"类资源的数量"<<endl;
for(i=0;i<Num_Resource;i++)
cin>>request[i];
Status result=Request_BankerALG(request,x);
switch(result)
{
case OVER_NEED:cout<<"资源申请失败(失败原因:申请的资源量超出进程当前最大需求量!)"<<endl;break;
case RES_NOT_ENOUGH:cout<<"资源申请失败(失败原因:申请的资源量超出系统当前剩余资源量!)"<<endl;break;
case NOT_SAFE:cout<<"资源申请失败(失败原因:申请后的状态不安全,可能存在进程死锁,无法完成资源申请!)"<<endl;break;
case OK:cout<<"进程"<<x<<"申请资源成功!"<<endl;break;
default:break;
}
}
void showMenu()//菜单显示
{
cout<<"\t\t|---------------------------------------------------------------|"<<endl;
cout<<"\t\t|\t\t\t2018年6月29日\t\t |"<<endl;
cout<<"\t\t|\t姓名:赵文浩 学号:16111204082 |"<<endl;
cout<<"\t\t|----------------------------MENU-------------------------------|"<<endl;
cout<<"\t\t|\t1. 读取进程和系统资源信息 |"<<endl;
cout<<"\t\t|\t2. 更新并显示进程和系统资源当前状态 |"<<endl;
cout<<"\t\t|\t3. 检测当前状态是否安全 |"<<endl;
cout<<"\t\t|\t4. 进程请求资源(避免死锁)-银行家算法 |"<<endl;
cout<<"\t\t|---------------------------------------------------------------|"<<endl;
}
2. 结果截图