首页 > 代码库 > 银行家算法

银行家算法

           银行家算法:

银行家算法是一种最有代表性的避免死锁的算法。又被称为“资源分配拒绝”法。

银行家算法中的数据结构:

(1)可利用资源向量Available。这是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数组,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。

(2)最大需求矩阵Max。这是一个n*m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。

(3)分配矩阵Allocation。这也是一个n*m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源。

(4)需求矩阵Need。这也是一个n*m的矩阵,用以表示每一个进程尚需的各类资源数。

 上述三个矩阵间存在下述关系:

             Need[i,j]=Max[i,j]-Allocation[i,j]

针对上述数据结构我们可以这样理解:

首先,我们把操作系统看作“银行家”,操作系统管理的资源看作“银行里的资金”,进程向操作系统请求分配资源相当于“用户向银行家贷款”。

那么,上述银行家算法中的数据结构可以解释为:

(1)向量Available是一个含有m个元素的数组,可以看作银行里有m种币种(像人民币,美元,欧元,英镑等)。如果Available[j]=K,则表示最初银行里Rj类币种的钱数为K

(2)最大需求矩阵Max是一个n*m的矩阵,可以看作用户需贷每种币种的最大数量。如果Max[i,j]=K,则表示第i个用户需要Rj类币种钱数最大为K

(3)分配矩阵Allocation也是一个n*m的矩阵,表示银行家把银行中每种币种的钱已贷给用户的数量。如果Allocation[i,j]=K,则表示用户i已贷得Rj类币种的数目为K

(4)需求矩阵Need也是一个n*m的矩阵,表示每一个用户还需要再贷每一类币种的数量。如果Need[i,j]=K,则表示用户i还需要Rj类币种的钱数为K

银行家算法:

Request[i]是进程Pi的请求向量,如果Request[i][j]=K,表示进程Pi需要KRj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:

(1)如果Request[i][j]<=Need[i,j],便转向步骤(2);否则认为出错,因为它所需的资源数已超过它所宣布的最大值。

(2)如果Request[i][j]<=Available[j],便转向(3);否则表示尚无足够资源,Pi需等待。

(3)系统试探着把资源分配给进程Pi,并修改下面的数据结构中的数值:

         Available[j]:=Available[j]-Request[i][j];

         Allocation[i,j]:=Allocation[i,j]+Request[i][j];

         Need[i,j]:=Need[i,j]-Request[i][j];

(4)系统执行安全性算法,检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,已完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进城Pi等待。

银行家算法可以这样理解:

Request[i]是用户Pi的请求向量,如果Request[i][j]=K,表示用户Pi需要Rj类币种的钱的数目为K。当用户提出请求时,银行家按下述步骤进行检查:

(1)如果Request[i][j]<=Need[i,j],便转向步骤(2);否则认为出错,因为现在用户所要求贷的钱数超过他原先预定的需贷的钱数。

(2)如果Request[i][j]<=Available[j],便转向步骤(3);否则表示银行中j类币种的钱数暂时已不能满足用户的需求,所以此时用户Pi需等待。

(3)银行家试探着把各个币种的钱分配给用户。

(4)银行家再通过安全性算法检查按上述方案是否能把各币种的钱贷给用户,如果能,则正式把钱贷给用户,否则,本次试探分配作废,恢复原来银行中各类币种的数量,让用户Pi等待。

安全性算法:

系统所执行的安全性算法可描述如下:

(1)设置两个向量:

     ①工作向量Work,它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全性算法开始时,Work:=Available

     ②Finish,它表示系统是否有足够的资源分配给进程,使之运行成功。开始时先做Finish[i]:=false;当有足够资源分配给进程时,再令Finish[i]:=true

(2)从进程集合中找到一个能满足下述条件的进程:

     ①Finish[i]=false

     ②Need[i,j]<=Work;若找到,执行步骤(3),否则,执行步骤(4)。

(3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:

     Work[j]:=Work[j]+Allocation[i,j];

     Finish[i]:=true;

     goto step;

(4)如果所有进程的Finish[i]=true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。

 

银行家算法代码:<摘自百度百科>

#include<STRING.H>
#include<stdio.h>
#include<stdlib.h>
#include<CONIO.H>/*用到了getch()*/
#defineM5/*进程数*/
#defineN3/*资源数*/
#defineFALSE0
#defineTRUE1
/*M个进程对N类资源最大资源需求量*/
intMAX[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
/*系统可用资源数*/
intAVAILABLE[N]={10,5,7};
/*M个进程已分配到的N类数量*/
intALLOCATION[M][N]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
/*M个进程已经得到N类资源的资源量*/
intNEED[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
/*M个进程还需要N类资源的资源量*/
intRequest[N]={0,0,0};
voidmain()
{
inti=0,j=0;
charflag;
voidshowdata();
voidchangdata(int);
voidrstordata(int);
intchkerr(int);
showdata();
enter:
{
printf("请输入需申请资源的进程号(从0到");
printf("%d",M-1);
printf("):");
scanf("%d",&i);
}
if(i<0||i>=M)
{
printf("输入的进程号不存在,重新输入!\n");
gotoenter;
}
err:
{
printf("请输入进程");
printf("%d",i);
printf("申请的资源数\n");
printf("类别:ABC\n");
printf("");
for(j=0;j<N;j++)
{
scanf("%d",&Request[j]);
if(Request[j]>NEED[i][j])
{
printf("%d",i);
printf("号进程");
printf("申请的资源数>进程");
printf("%d",i);
printf("还需要");
printf("%d",j);
printf("类资源的资源量!申请不合理,出错!请重新选择!\n");
gotoerr;
}
else
{
if(Request[j]>AVAILABLE[j])
{
printf("进程");
printf("%d",i);
printf("申请的资源数大于系统可用");
printf("%d",j);
printf("类资源的资源量!申请不合理,出错!请重新选择!\n");
gotoerr;
}
}
}
}
changdata(i);
if(chkerr(i))
{
rstordata(i);
showdata();
}
else
showdata();
printf("\n");
printf("按'y'或'Y'键继续,否则退出\n");
flag=getch();
if(flag=='y'||flag=='Y')
{
gotoenter;
}
else
{
exit(0);
}
}
/*显示数组*/
voidshowdata()
{
inti,j;
printf("系统可用资源向量:\n");
printf("***Available***\n");
printf("资源类别:ABC\n");
printf("资源数目:");
for(j=0;j<N;j++)
{
printf("%d",AVAILABLE[j]);
}
printf("\n");
printf("\n");
printf("各进程还需要的资源量:\n");
printf("******Need******\n");
printf("资源类别:ABC\n");
for(i=0;i<M;i++)
{
printf("");
printf("%d",i);
printf("号进程:");
for(j=0;j<N;j++)
{
printf("%d",NEED[i][j]);
}
printf("\n");
}
printf("\n");
printf("各进程已经得到的资源量:\n");
printf("***Allocation***\n");
printf("资源类别:ABC\n");
for(i=0;i<M;i++)
{
printf("");
printf("%d",i);
printf("号进程:");
/*printf(":\n");*/
for(j=0;j<N;j++)
{
printf("%d",ALLOCATION[i][j]);
}
printf("\n");
}
printf("\n");
}
/*系统对进程请求响应,资源向量改变*/
voidchangdata(intk)
{
intj;
for(j=0;j<N;j++)
{
AVAILABLE[j]=AVAILABLE[j]-Request[j];
ALLOCATION[k][j]=ALLOCATION[k][j]+Request[j];
NEED[k][j]=NEED[k][j]-Request[j];
}
}
/*资源向量改变*/
voidrstordata(intk)
{
intj;
for(j=0;j<N;j++)
{
AVAILABLE[j]=AVAILABLE[j]+Request[j];
ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j];
NEED[k][j]=NEED[k][j]+Request[j];
}
}
/*安全性检查函数*/
intchkerr(ints)
{
intWORK,FINISH[M],temp[M];
inti,j,k=0;
for(i=0;i<M;i++)FINISH[i]=FALSE;
for(j=0;j<N;j++)
{
WORK=AVAILABLE[j];
i=s;
while(i<M)
{
if(FINISH[i]==FALSE&&NEED[i][j]<=WORK)
{
WORK=WORK+ALLOCATION[i][j];
FINISH[i]=TRUE;
temp[k]=i;
k++;
i=0;
}
else
{
i++;
}
}
for(i=0;i<M;i++)
if(FINISH[i]==FALSE)
{
printf("\n");
printf("系统不安全!本次资源申请不成功!\n");
printf("\n");
return1;
}
}
printf("\n");
printf("经安全性检查,系统安全,本次分配成功。\n");
printf("\n");
printf("本次安全序列:\n");
printf("进程依次为");
for(i=0;i<M;i++)
{
printf("%d",temp[i]);
printf("->");
}
printf("\n");
return0;
}