实验目的
银行家算法是避免死锁的代表性算法。本实验旨在加深了解有关资源申请、避免死锁、状态安全性等概念,并体会和运用避免死锁的具体实施方法。然后依照本实验,自行设计模拟程序。
实验内容及步骤
提示1
我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。操作系统按照银行家制定的规则为进程分配资源。
当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。
提示2
安全状态:如果存在一个由系统中所有进程构成的安全序列P1,…,Pn,则系统处于安全状态。安全状态一定是没有死锁发生。
不安全状态:不存在一个安全序列。不安全状态一定导致死锁。
安全序列:一个进程序列{P1,…,Pn}是安全的,如果对于每一个进程Pi(1≤i≤n),它以后尚需要的资源量不超过系统当前剩余资源量与所有进程Pj (j < i )当前占有资源量之和。
提示3
设requesti为进程p[i]的请求向量,如果requesti[j]=K,表示进程p[i]需要K个Rj资源。当系统发出请求后,系统按下述步骤开始检查:
1)如果requesti[j]<=need[i][j],转向步骤2;否则报告出错,申请的资源已经大于它需要的最大值。
2)如果requesti[j]<=available[j],转向步骤3;否则报告出错,尚无足够的资源。
3)系统试探着把资源分配给p[i],并修改下列数据
结构中的值:
available[j]=available[j]request[j]
allocation[i][j]=allocation[i][j]+request[j]
need[i][j]=need[i][j]request[j]
4)系统进行安全性算法,检查此次分配后,系统是否还处于安全状态,若安全,把资源分配给进程p[i];否则,恢复原来的资源分配状态,让进程p[i]等待。
提示4
安全性算法:
int work[RESOURCE_NUMBER];
bool finish[PROCESS_NUMBER];
- Work=Available;
Finish=false; - 寻找满足条件的i:
A、Finish[i]=false;
B、Need[i]≤Work;
如果不存在,则转4) - Work:=Work+Allocation[i]; Finish[i]:=true;转2)
- 若对所有i,Finish[i]=true,则系统处于安全状态,
否则处于不安全状态
提示5(银行家算法的程序流程图)
数据结构:
int Allocation[100][100],Max[100][100],Need[100][100],Available[100];
//Allocation数组表示已分配资源,Max数组表示进程所需要资源,Need数组表示进程完成还需要的资源,Available数组表示剩余资源
int n,m;//n为进程数,m为资源类型数量
int xulie[100];//储存安全序列
具体代码:
#include <iostream>
using namespace std;
int Allocation[100][100],Max[100][100],Need[100][100],Available[100];
int n,m;
int xulie[100];//安全序列
bool issafe() //判断是否是安全状态
{
bool Finish[n];
int work[m];
for(int i=0;i<n;i++) Finish[i]=false;
for(int i=0;i<m;i++) work[i]=Available[i];
bool fac=true;
for(int i=0;i<n;i++) //寻找下一个进程
{
for(int j=0;j<n;j++)
{
bool can=true;
for(int k=0;k<m;k++)
{
if(Need[j][k]<=work[k]&&Finish[j]!=true) continue; //找到进程
else
{
can=false;
break;
}
}
if(can)
{
for(int k=0;k<m;k++) work[k]+=Allocation[j][k];
Finish[j]=true; //表示进程可完成
xulie[i]=j; //存储序列
break;
}
if(j==n-1)
{
fac=false;
}
}
if(fac==false) break; //找不到进程,退出循环
}
return fac;
}
void print()//打印当前资源状态
{
cout<<endl<<"当前可利用的资源为:"<<endl;
cout<<"A B C"<<endl;
for(int i=0;i<m;i++) cout<<Available[i]<<" ";
cout<<endl;
cout<<"当前系统资源情况为:"<<endl;
cout<<"PID Max Allocation Need"<<endl;
for(int i=0;i<n;i++)
{
cout<<"P"<<i<<" ";
for(int j=0;j<m;j++)
{
cout<<Max[i][j]<<" ";
}
cout<<" ";
for(int j=0;j<m;j++)
{
cout<<Allocation[i][j]<<" ";
}
cout<<" ";
for(int j=0;j<m;j++)
{
cout<<Need[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
cout<<"请输入资源类型的种类m:"; //输入初始信息
cin>>m;
cout<<"请输入系统进程的个数n:";
cin>>n;
cout<<"请输入各种资源的数量"<<endl;
for(int j=0;j<m;j++) cin>>Available[j];
cout<<"请输入进程需要的资源"<<endl;
string pid[n];
for(int i=0;i<n;i++)
{
cin>>pid[i];
for(int j=0;j<m;j++)
{
cin>>Max[i][j];
}
}
cout<<"请输入已分配给进程的资源"<<endl;
for(int i=0;i<n;i++)
{
cin>>pid[i];
for(int j=0;j<m;j++)
{
cin>>Allocation[i][j];
Available[j]-=Allocation[i][j];
Need[i][j]=Max[i][j]-Allocation[i][j];
}
}
print(); //打印资源状态
if(issafe()) //判断此时是否是安全状态
{
cout<<"当前为安全状态,安全序列为:";
for(int i=0;i<n;i++) cout<<xulie[i]<<" ";
cout<<endl;
}
else cout<<"状态不安全"<<endl;
while(1)
{
cout<<"请输入要分配资源的进程"<<endl;
int num,a[m];
cin>>num;
cout<<"请输入各种资源的数量"<<endl;
for(int i=0;i<m;i++) cin>>a[i];
bool duan=true;
for(int i=0;i<m;i++)
{
if(a[i]>Need[num][i]||a[i]>Available[i]) //判断请求资源是否大于剩余资源量或者需求资源量
{
duan=false;
break;
}
}
if(duan)
{
for(int i=0;i<m;i++) //修改资源状态
{
Allocation[num][i]+=a[i];
Need[num][i]-=a[i];
Available[i]-=a[i];
}
if(issafe()) //判断此时是否是安全状态
{
cout<<endl<<"资源分配成功"<<endl;
cout<<"当前为安全状态,安全序列为:";
for(int i=0;i<n;i++) cout<<xulie[i]<<" ";
}
else
{
cout<<"状态不安全,请重新分配"<<endl;
for(int i=0;i<m;i++) //分配失败,恢复资源状态
{
Allocation[num][i]-=a[i];
Need[num][i]+=a[i];
Available[i]+=a[i];
}
}
print();
}
else
{
cout<<"剩余资源不足或输入的资源数量大于需求量,请重新分配"<<endl;
print();
}
}
}
/*
P0 7 5 3
P1 3 2 2
P2 9 0 2
P3 2 2 2
P4 4 3 3
P0 0 1 0
P1 2 0 0
P2 3 0 2
P3 2 1 1
P4 0 0 2
*/
运行结果:
收获与体会:
本次实验是对于银行家算法的实现。通过安全性算法以及资源分配算法实现实验要求。