一、实验目的:
通过对银行家算法的模拟加深对避免死锁的理解,掌握银行家算法和安全性测试算法;
二、实验内容:
系统中有m个同类资源,被n个进程共享,每个进程对资源的最大需求数分别为S1、S2、…、Sn,且Max(Si)<=m(i=1,2,…,n)。进程可以动态地申请资源和释放资源。编写一个程序,实现银行家算法模拟分配资源以及进行安全性检测。当系统将资源分配给某一进程而不会死锁时,就分配之。否则,推迟分配,并显示适当信息。
三、程序分析与设计:
1、算法思想和算法流程设计
系统在进行资源分配之前,应先计算此次资源分配的安全性,若此次分配不会导致系统进入不安全状态,才可将资源分配给进程,否则另进程等待。
四、源程序
#include <cstdlib>
#include <iostream>
using namespace std;
#define M 3 //M个资源
#define N 5 //N个进程
/**定义初始化数组 **/
int Available[M],//可利用资源向量
Max[N][M],//最大需求矩阵 定义了每一个进程对M类资源的最大需求
Allocation[N][M],//分配矩阵 定义了每一类资源当前已分配给每一进程的资源数
Need[N][M],//需求矩阵 表示每一个进程尚需的资源数
Request[M];//进程请求向量
int ucjc;//用户选择的进程号
void sfp(int n);//进行试分配
void Print(); //用于打印输出表格的函数
void tryfenpei(int i);//试分配函数
void refenpei(int i);//恢复数据函数
void safecheck(int s);//安全检测函数
/**
用户自定义进程
**/
void csf()
{
int*p;
p=(int*)malloc(M*sizeof(int));
cout<<"请输入系统中现有资源个数,长度为3:"<<endl;
int flag=1;
while(flag){
for(int i=0;i<M;i++)//用户自定义初始化Available[]可利用资源向量
{
cin>>Available[i];
}
flag=0;
for(int j=0; j<M;j++){
if(Available[j]<0) {
cout<<"**********输入的数字无效,请重新输入***********"<<endl;
flag=1;
break; }
}
}
for(int i=0;i<3;i++)
{
for(int j=0;j<N;j++)//N个进程
{
if(i==0){//初始化最大需求矩阵 Max[][]
int flag=1;
while(flag){
cout<<"请输入进程"<<j<<"需要的最大资源数,长度为3:";
for(int m=0;m<M;m++)
{cin>>Max[j][m];}
flag=0;
for(int m=0;m<M;m++){
if(Max[j][m]<0){
cout<<"*********输入的数字无效,请重新输入*********"<<endl;
flag=1; break;
}
}
}
}
if(i==1){//初始化分配矩阵 Allocation[][]
int flag=1;
while(flag){
cout<<"请输入进程"<<j<<"当前已分配的资源数,长度为3:";
for(int m=0;m<M;m++)
{cin>>Allocation[j][m];}
flag=0;
for(int m=0;m<M;m++){
if(Allocation[j][m]<0){
cout<<"*********输入的数字无效,请重新输入*********"<<endl;
flag=1; break;
}
}
}
}
if(i==2)//需求矩阵Need[][]
{
for(int m=0;m<M;m++)
Need[j][m]= Max[j][m]-Allocation[j][m];
}
}
}
}
/**
系统尝试分配资源
Available[M]可利用资源向量
Allocation[N][M]分配矩阵
Need[N][M]需求矩阵
Request[M]进程请求向量
**/
void sfp(int n)
{
for(int i=0;i<M;i++)
{
Available[i]=Available[i]-Request[i];
Allocation[n][i]=Allocation[n][i]+Request[i];
Need[n][i]=Need[n][i]-Request[i];
}
}
/**
安全检测
work[]工作向量,表示系统可提供给进程继续运行所需的各类资源数目
finish[] 表示系统是否有足够的资源分配给进程
**/
int safecheck()
{
int work[M],Finish[N],flag=1;
for(int i=0;i<M;i++)
work[i]=Available[i];
for(int i=0;i<N;i++)
Finish[i]=false;
int a[N];
for(int i=0;i<N;i++){
static int m=0,ci;
for( ci=0;ci<N;ci++)
//当进程获得资源后,可顺利执行直至完成,并释放出分配给它的资源
if(Finish[ci]==false&&Need[ci][0]<=work[0]&&Need[ci][1]<=work[1]&&Need[ci][2]<=work[2]){
for(int j=0;j<M;j++)
work[j]=Allocation[ci][j]+work[j];
Finish[ci]=true;
a[m++]=ci;
}
}
int i;
for( i=0;i<N;i++)
//如果所有进程的finish[]=true都满足,则表示系统处于安全状态,否则处于不安全状态
if(Finish[i]!=true) { cout<<"*****系统不安全! 本次资源申请不成功!*****"<<endl; return 0;break;}
if(i==N){
Print();
cout<<"得到安全序列:";
for(int i=0;i<N;i++)
if (i<N-1) cout<<"p"<<a[i]<<"->";
else cout<<"p"<<a[i]<<endl;\
return 1;
}
}
/**
恢复数据函数
执行安全性算法,发现此次资源分配后系统处于不安全状态
将本次试探作废,恢复成原来的资源分配状态
**/
void refenpei(int i)
{
for(int f=0;f<M;f++)
{
Available[f] = Available[f] + Request[f];
Allocation[i][f] = Allocation[i][f] - Request[f];
Need[i][f] = Need[i][f]+Request[f];
}
}
void Print()
{
int i,j;
cout<<" 进程个数 : "<<N<<" 资源个数: "<<M<<endl;
cout<<endl;
cout<<"|*****|***********|***********|**********|***********|"<<endl;
cout<<"|****|最大需求矩阵|已分配矩阵-|-需求矩阵-可用资源向量|"<<endl;
cout<<"| 资源| Max | Allocation | Need | Available |"<<endl;
cout<<"| | A B C | A B C | A B C | A B C |"<<endl;
cout<<"|进程 | | | | |"<<endl;
cout<<"|*****|**********|************|**********|***********|"<<endl;
for(i=0;i<5;i++){
cout<<"| p"<<i<<" | ";
for(j=0;j<3;j++)
{
cout<<Max[i][j]<<" ";
}
cout<<"|";
for(j=0;j<3;j++)
{
cout<<" "<<Allocation[i][j];
}
cout<<" |";
for(j=0;j<3;j++)
{
cout<<" "<<Need[i][j];
}
cout<<" |";
if(i==0)
{
for(j=0;j<3;j++)
{
cout<<" "<<Available[j];
}
cout<<" |";
}
if(i>0)
{
cout<<" |";
}
cout<<endl;
}
cout<<"|*****|**********|************|**********|***********|"<<endl;
}
int main(int argc, char *argv[])
{
char log;
int flag=1;
int work[M];
int finish[N];
int i;
cout<<"********准备输入初始化数据资源 *******"<<endl;
csf();
cout<<"***********初始化数据资源完成*************"<<endl;
cout<<"***********检测当前系统资源是否安全***********"<<endl;
for(int i=0;i<M;i++)
work[i]=Available[i];
for(int i=0;i<N;i++)
finish[i]=false;
int a[N];
for(int i=0;i<N;i++)
{
static int m=0,ci;
for( ci=0;ci<N;ci++)
if(finish[ci]==false&&Need[ci][0]<=work[0]&&Need[ci][1]<=work[1]&&Need[ci][2]<=work[2])
{
for(int j=0;j<M;j++)
work[j]=Allocation[ci][j]+work[j];
finish[ci]=true;
a[m++]=ci;
}
}
for( i=0;i<N;i++)
if(finish[i]!=true) { cout<<"*****系统不安全! 本次资源申请不成功!*****"<<endl;break;}
if(i==N)
{
Print();
cout<<"得到安全序列:";
for(int i=0;i<N;i++)
if (i<N-1) cout<<"p"<<a[i]<<"->";
else cout<<"p"<<a[i]<<endl;
}
cout<<"***********请输入发起请求的进程号P[0-4]*********"<<endl;
while(cin>>ucjc)
{
if(ucjc>4||ucjc<0)
cout<<"*********请求的进程号无效,请重新输入!"<<endl;
else break;
}
cout<<"您输入的进程为P["<<ucjc<<"]进程"<<endl;
cout<<"P["<<ucjc<<"]"<<"的需求量为:";
for(int i=0;i<M;i++)
cout<<Need[ucjc][i]<<" ";
cout<<endl;
cout<<"输入请求资源向量:";
for(int i=0;i<M;i++)
{ while(cin>>Request[i])
{
if(Request[i]<0)
cout<<"*********输入的数字无效,请重新输入!"<<endl;
else if(Request[i]>Need[ucjc][i]) cout<<"错误!超出进程需求量"<<endl;
else if(Request[i]>Available[i]) cout<<"错误!系统还没有足够的可用资源量满足进程需要"<<endl;
else break;
}
}
cout<<"输入成功,您输入的是:"<<Request[0]<<" "<<Request[1]<<" "<<Request[2]<<endl;
cout<<"开始执行银行家算法,下面进行试分配"<<endl;
sfp(ucjc);//进行试分配
cout<<"**********试分配完成!**********"<<endl;
cout<<"**********进行安全性检测!**********"<<endl;
if(!safecheck()){
refenpei(ucjc);
cout<<"***** 恢复数据,恢复后的状态为:*****"<<endl;
Print();
};
system("PAUSE");
return EXIT_SUCCESS;
}