一、银行家算法
1.资源请求reqresource()函数:
设 Requesti是进程Pi的请求向量,如果Requesti[j]=K,则表示进程Pi需要K个Ri类型的资源。当Pi发出资源请求后,系统会先下列步骤进行检查
(1) 若 Requesti[j] ≤ Need[i,j],转向步骤(2),否则出错。
(2) 若 Requesti[j] ≤ Available[j],转向步骤(3),否则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等待。
2.安全性算法issafe() 函数:
(1) 初始化:设置两个向量Work[M]和Finish[N]
Work – 系统可提供给进程继续运行所需各类资源数,初态赋值Available
Finish – 系统是否有足够资源分配给进程,初值FALSE.
(2) 从进程集合中满足下面条件进程:
Finish[i] = FALSE; Need[i,j] ≤ Work[j];
若找到,执行步骤(3),否则,执行步骤(4)。
(3) 进程Pi获得资源,可顺利执行,完成释放所分配的资源。
Work[j] = Work[j]+Allocation[i,j]; Finish[i] = TRUE; go to step(2);
(4) 若所有进程Finish[i] = TRUE,表示系统处于安全状态,否则处于不安全状态。
先对用户提出的请求进行合法性检查,即检查请求的是否不大于需要的,是否不大于可利用的。 若请求合法,则进行试分配。最后对试分配后的状态调用安全性检查算法进行安全性检查。 若安全,则分配,否则,不分配,恢复原来状态,拒绝申请。
二、定义数据结构
int Resource[10]; //各类资源总数量
int Max[10][10]; //最大需求矩阵
int Allocation[10][10]; //分配矩阵
int Need[10][10]; //需求矩阵
int Available[10]; //可利用资源向量
int Work[10]; //工作向量 ,表示系统可提供给进程继续运行所需的各类资源数目
int Finish[10]; //完成向量
int List[10]; //存放安全序列的下标序列
三、算法实例
(1)P1请求资源:P1发出请求向量Request1(1,0,2)。
(2)P4请求资源:P4发出请求向量Request4(3,3,0)。
(3)P0请求资源:P0发出请求向量Request0(0,2,0)。
四、算法实现
#include<bits/stdc++.h>
using namespace std;
int Resource[10]; //各类资源总数量
int Max[10][10]; //最大需求矩阵
int Allocation[10][10]; //分配矩阵
int Need[10][10]; //需求矩阵
int Available[10]; //可利用资源向量
int Work[10]; //工作向量 ,表示系统可提供给进程继续运行所需的各类资源数目
int Finish[10]; //完成向量
int List[10]; //存放安全序列的下标序列
int N,M;
//初始化函数
void initial()
//创建初始资源状态:先输入 Resource、Max和 Allocation,再计算出 Need、Available。
{
int i,j;
// 各类资源总数量
printf("Resource--输入M种资源的总数量:\n");
for(i=0;i<M;i++)
{
cin>>Resource[i];
Available[i]=Resource[i];
}
//最大需求矩阵
printf("Max--输入N个进程分别对M种资源的最大需求量:\n");
for(i=0;i<N;i++){
for(j=0;j<M;j++){
cin>>Max[i][j];
}
}
//分配矩阵
printf("Allocation--输入N个进程获得M种资源的数量:\n");
for(i=0;i<N;i++){
for(j=0;j<M;j++){
cin>>Allocation[i][j];
}
}
//根据Max和Allocation计算Need
for(i=0;i<N;i++){
for(j=0;j<M;j++){
Need[i][j]=Max[i][j]-Allocation[i][j];
}
}
//Available为可变资源向量,其值随分配和回收而动态改变
for(i=0;i<M;i++){
for(j=0;j<N;j++){
Available[i]=Available[i]-Allocation[j][i];
}
}
}
//打印函数
void printState()
//输出当前的状态表
{
int i,j;
cout<<"\n\t\tT0时刻资源分配情况\n\n";
cout<<"进程\\资源\tMax\t\tAllocation\tNeed\t\tAvailable"<<endl;
for(i=0;i<N;i++){
if(i==0){
cout<<"P"<<i<<"\t\t";
for(j=0;j<M;j++) cout<<Max[i][j]<<" ";
cout<<"\t\t";
for(j=0;j<M;j++) cout<<Allocation[i][j]<<" ";
cout<<"\t\t";
for(j=0;j<M;j++) cout<<Need[i][j]<<" ";
cout<<"\t\t";
for(j=0;j<M;j++) cout<<Available[j]<<" ";
cout<<endl;
}
else{
cout<<"P"<<i<<"\t\t";
for(j=0;j<M;j++) cout<<Max[i][j]<<" ";
cout<<"\t\t";
for(j=0;j<M;j++) cout<<Allocation[i][j]<<" ";
cout<<"\t\t";
for(j=0;j<M;j++) cout<<Need[i][j]<<" ";
cout<<endl;
}
}
cout<<endl;
}
//判断进程是否能够完成
int isfinish()
//若同时满足Finish[i]=FALSE和Need[i][j]≤Work[j]},则返回该进程下标 i并修改Finish[i]=TRUE,否则返回-1。
{
int i,j,count; //count表示资源种类数
for(i=0;i<N;i++)
{
for(j=0,count=0;j<M;j++)
if(Finish[i]==0&&Need[i][j]<=Work[j])
{
count++; //当有一种资源能够分配给该进程的该种资源时,count加1
}
if(count==3) //count=3表示有足够的资源分配给该进程的三种资源
{
for(j=0;j<M;j++)
Work[j]+=Allocation[i][j]; //分配完后将该进程的Allocation加到Work上
Finish[i]=1; //将该进程标记为1,相当于Finish[i]=TRUE
return i;
}
}
return -1;
}
//安全性算法
int issafe()
//判定当前状态是否为安全状态 (返回 TRUE 或 FALSE),把安全序列的下标放入 List[N]数组。
{
int i,a,count=0; //a表示进程下标
for(i=0;i<M;i++)
Work[i]=Available[i];
//初始FFinish[i]为FALSE,也就是0
for(i=0;i<N;i++)
Finish[i]=0;
for(i=0;i<N;i++)
{
a=isfinish();
if(a!=-1)
{
List[i]=a;
count++;//进程数加1
}
}
if(count==5)
return 1;//返回1表示安全
else
return 0;//返回0表示不安全
}
void printList( )
//输出安全序列表
{
int i,j;
cout<<"\nT0时刻安全序列表\n\n";
cout<<"进程\tWork\tNeed\tAllocation\tWork+Allocation\tFinish"<<endl;
for(j=0;j<M;j++)
{
Work[j]=Available[j];
}
for(i=0;i<N;i++){
cout<<"P"<<List[i]<<"\t";
for(j=0;j<M;j++) cout<<Work[j]<<" ";
cout<<"\t";
for(j=0;j<M;j++) cout<<Need[List[i]][j]<<" ";
cout<<"\t";
for(j=0;j<M;j++) cout<<Allocation[List[i]][j]<<" ";
cout<<"\t\t";
for(j=0;j<M;j++) cout<<Work[j]+Allocation[List[i]][j]<<" ";
cout<<"\t\t";
cout<<"TRUE"<<endl;
for(j=0;j<M;j++) Work[j]+=Allocation[List[i]][j];
}
cout<<endl;
}
//银行家算法
void reqresource(int i, int Request[])
//表示第 i个进程请求 M类资源 request[]
{
int flag,count1,count2;
int j;
//第一步: 判断条件 Request[j]≤Need[i][j]
for(j=0,count1=0;j<M;j++){
if(Request[j]<=Need[i][j])
count1++;
}
//第二步: 判断条件 Request[j]≤Available[j]
for(j=0,count2=0;j<M;j++){
if(Request[j]<=Available[j])
count2++;
}
if(count2!=3)
printf("\n尚无足够的资源,第%d个进程需等待。\n",i);
//第三步: 系统试探把资源分配给进程Pi
if(count2==3&&count1==3)
{
for(j=0;j<M;j++)
{
Available[j]=Available[j]-Request[j];
Allocation[i][j]=Allocation[i][j]+Request[j];
Need[i][j]=Need[i][j]-Request[j];
}
if(issafe()==0)
{
printf("\n不存在安全序列,不是安全状态。\n");
for(j=0;j<M;j++)
{
Available[j]=Available[j]+Request[j];
Allocation[i][j]=Allocation[i][j]-Request[j];
Need[i][j]=Need[i][j]+Request[j];
}
}
else
{
printf("\n是安全序列!....分配成功!\n");
printf("安全序列为:");
for(j=0;j<N;j++){
printf("P%d ",List[j]);
}
printList();
}
}
cout<<endl;
}
int main()
{
cout<<"请输入进程数:";
cin>>N;
cout<<"请输入资源种类数:";
cin>>M;
int reqid=-1,j,req[M];
initial();
printState();
if(issafe()==0)
{
printf("初始化状态不安全!\n");
}
else
{
printf("\n初始化状态安全!\n");
printList();
printf("请输入请求资源的进程id:");
cin>>reqid;
while(reqid>=0 && reqid<N) //输入进程 reqid是否合法
{
printf("请输入进程P%d请求的资源向量Request:",reqid);
for(j=0;j<M;j++)
{
cin>>req[j];
}
reqresource(reqid, req);
printf("输入请求资源的进程id:");
cin>>reqid;
}
}
}
五、结果
1.初始状态
2.资源请求
(1)P1请求资源:P1发出请求向量Request1(1,0,2)。
(2)P4请求资源:P4发出请求向量Request4(3,3,0)。
(3)P0请求资源:P0发出请求向量Request0(0,2,0)。