目录
1、什么是银行家算法
银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。
2、题目
3、解决过程
4、为了实现银行家算法,在系统中必须设置这样四个数据结构:
Available向量:系统中可利用的资源数目
Max矩阵:每个进程对每种资源的最大需求
Allocation矩阵:每个进程已分配的各类资源的数目
Need矩阵:每个进程还需要的各类资源数 其中三个矩阵间存在下述关系: Need[i,j] = Max[i,j] - allocation[i, j]
5、将银行家算法的逻辑转化为自然语言:
设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当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等待。
6、源码:
//#include<iostream>
#include<stdio.h>
//using namespace std;
//p进程数
int p ;
//r资源种类
int r ;
//最大需求矩阵
int maxs[10][10]={{0,0,4,4},{2,7,5,0},{3,6,10,10},{0,9,8,4},{0,6,6,10}};
//分配矩阵
int allocation[10][10]={{0,0,3,2},{1,0,0,0},{1,3,5,4},{0,3,3,2},{0,0,1,4}};
//需求矩阵
int need[10][10]={{0,0,1,2},{1,7,5,0},{2,3,5,6},{0,6,5,2},{0,6,5,6}};
//可用资源向量
int available[10]={1,6,2,2};
//请求向量当前进程对各类资源的申请量,算法的入口参数
int request[10];
//输入函数
void infInput()
{
int i,j;
//cout<<"请输入最大需求矩阵 max\n";
printf("请输入最大需求矩阵");
for(i=0; i<p; i++)
{
for(j=0; j<r; j++)
{
//cin>>maxs[i][j];
scanf("%d",&maxs[i][j]);
}
}
//cout<<"请输入分配矩阵 allocation\n";
printf("请输入分配矩阵 allocation\n");
for(i=0; i<p; i++)
{
for(j=0; j<r; j++)
{
//cin>>allocation[i][j];
scanf("%d",&allocation[i][j]);
}
}
//cout<<"请输入需求矩阵 need\n";
printf("请输入需求矩阵 need\n");
for(i=0; i<p; i++)
{
for(j=0; j<r; j++)
{
//cin>>need[i][j];
scanf("%d",&need[i][j]);
}
}
//cout<<"请输入可用资源向量 available\n";
printf("请输入可用资源向量 available\n");
for(i=0; i<r; i++)
{
//cin>>available[i];
scanf("%d",&available[i]);
}
}//比较函数
//比较进程为 m 中的元素全大于 n 中的元素返回 1,否则返回 0
int compare(int m[],int n[])
{
int i;
for(i=0; i<r; i++)
{
if(m[i]<n[i])
{
return 0;
}
}
return 1;
}
//安全性检验函数,检测是否存在安全序列
int stest()
{
int i,j,k,l,flag=0;
int finish[p];
int work[r];
for(i=0; i<p; i++)
{
finish[i]=0;
//vis 为 1 即表示 available 满足第 i 进程的资源需要
}
for(i=0; i<r; i++)
{
work[i]=available[i];
}
//cout<<"分配序列: \n";
//cout<<" allocation need avilable"<<endl;
printf("分配序列: \n");
printf("allocation need avilable");
for(k=0; k<p; k++)
{
for(i=0; i<p; i++)
{
if(finish[i]==1)
{
continue;
}
else{
//available>=need
if(compare(work,need[i]))
{
finish[i]=1;
//cout<<'\n'<<"进程"<<i+1<<'\t';
printf("\n进程%d\t",i+1);
flag=1;
for (j =0; j<r; j++)
{
printf(" %2d ", allocation[i][j]);
}
//cout<<" ";
printf(" ");
for (j = 0; j < r; j++)
{
printf(" %2d ", need[i][j]);
}
//cout<<" ";
printf(" ");
for (j = 0; j <r; j++)
{
printf(" %2d ", work[j] +allocation[i][j]);
}
for(l=0; l<r; l++)
{
work[l]=work[l]+allocation[i][l];
//进程完成,释放资源
}
break;
}
if(i<p)
continue;
}
if(flag==1)
{
break;
}
}
}
//cout<<'\n';
printf("\n");
for(l=0; l<p; l++)
{
if(finish[l]==0)
{
//不存在安全序列
return 0;
}
}
//存在安全序列
return 1;
}
//申请进程后的安全性检验函数
void rtest(int n)
{
int j;
//n=n-1;
if(compare(available,request)&&compare(need[n-1],request))//available>=request并且 need >=request
{
for(j=0; j<r; j++)
{
allocation[n-1][j]=allocation[n-1][j]+request[j];
need[n-1][j]=need[n-1][j]-request[j];
available[j]=available[j]-request[j];
}
if(stest())
{
//cout<<"允许"<<n<<"进程申请资源! \n";
printf("允许%d进程申请资源! \n",n);
}
else
{
//cout<<"不允许"<<n<<"进程申请资源! \n";
printf("不允许%d进程申请资源! \n",n);
for(j=0; j<r; j++)
{
allocation[n-1][j]=allocation[n-1][j]-request[j];
need[n-1][j]=need[n-1][j]+request[j];
available[j]=available[j]+request[j];
}
}
}
else
{
//cout<<"申请资源量越界! \n";
printf("申请资源量越界! \n");
}
}
int main()
{
int i,n; //n-第 n 个资源申请
//cout<<"请输入进程数: ";
printf("请输入进程数: ");
//cin>>p;
scanf("%d",&p);
//cout<<"请输入资源种类数: ";cin>>r;
printf("请输入资源种类数: ");
scanf("%d",&r);
//默认状态 4、 3
//infInput();//输入函数
if(stest()==1)
{
//cout<<"存在安全序列,初始状态安全。 \n";
printf("存在安全序列,初始状态安全。 \n");
}
else
{
//cout<<"不存在安全序列,初始状态不安全。 \n";
printf("不存在安全序列,初始状态不安全。 \n");
}
//cout<<"请输入发出请求向量 request 的进程编号: ";
//cin>>n;
//cout<<"请输入请求向量 request\n";
printf("请输入发出请求向量 request 的进程编号: ");
scanf("%d",&n);
printf("请输入请求向量 request\n");
for(i=0; i<r; i++)
{
//cin>>request[i];
scanf("%d",&request[i]);
}
rtest(n);
return 0;
}