实验银行家算法.docx
《实验银行家算法.docx》由会员分享,可在线阅读,更多相关《实验银行家算法.docx(15页珍藏版)》请在冰豆网上搜索。
![实验银行家算法.docx](https://file1.bdocx.com/fileroot1/2023-4/17/c1f8606b-8514-4272-b13f-6d08b2e80fc6/c1f8606b-8514-4272-b13f-6d08b2e80fc61.gif)
实验银行家算法
实验三银行家算法
一、实验目的和意义
了解掌握银行家算法,学会模拟实现资源分配,同时有要求编写和调试一个系统分配资源的简单模拟程序,观察死锁产生的条件,并使用适当的算法,有效的防止和避免死锁的发生
二、方案设计及开发过程
1.实验背景
在多道程序系统中,虽可借助与多个进程的并发执行,来改善系统的资源利用率,提高系统的吞吐量,但可能发生一种危险---死琐。
产生死锁的原因可归结为两点:
1:
竞争资源。
当系统中供多个进程共享的资源如打印机、公用队列等,其数目不足以满足诸进程的需要时,会引起诸进程对资源的竞争而产生死锁。
2:
进程间推进顺序非法。
进程在运行过程中,请求和释放资源的顺序不当,也同样会导致产生进程死锁。
最有代表性的避免死锁的算法,是Dijkstra的银行家算法。
这是由于该算法能用与银行系统现金贷款的发放而得名的。
2.算法描述
设Request[i]是进程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,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
3.数据结构
银行家算法中的数据结构:
(1)可利用资源向量Available。
这是一个含有n个元素的数组,其中的每一个元素代表一类可利用的资源数目,其初始值是系统中所配置的该类全部可用资源的数目,其数值随该类资源的分配和回收而动态地改变。
如果Available[j]=K,则表示系统中现有Rj类资源K个。
(2)最大需求矩阵Max。
这是一个m*n的矩阵,它定义了系统中n个进程中每一个进程对m类资源的最大需求。
如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。
(3)分配矩阵Allocation。
这也是一个m*n的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。
如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的数目为K。
(4)需求矩阵Need。
这也是一个n*m的矩阵,用以表示每一个进程尚需的各类资源数。
如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。
(5)工作数组Work.。
这是一个含有n个元素的数组,它代表可以提供分配的资源数,初始值是Available中的数值,随着资源的回收,它的值也会改变,公式是Work[i]=Work[i]+Allocation[i]。
4.主要函数说明
主要函数主要有四个:
(1)Main()主函数:
用来显示资源的分配情况和提示信息,同时用Main函数来调用其它子程序。
(2)Safe()函数:
用来检查是否有安全序列,如果存在则返回一个‘1’给主函数,否则返回‘0’。
(3)Disp()函数:
用来显示随机生成的资源包括Max、Need、Allocation、Available。
(4)Request()函数:
用来进行资源请求,分为手动的和随机申请。
同时对申请的资源进行判断,检查申请是否有效,如果有效则返回一个‘1’给主函数,否则返回‘0’。
5.算法流程图
N
Y
Y
N
N
Y
N
Y
Y
三、调试记录与分析
在调试过程中为了显示安全序列的检查状况,在检查Available是否满足Need时要检查m*n遍,并存在表达有歧异,经过修改后,就不需要全部检查,而是Available只要有一个不满足Need就停止检查。
图3.1修改前
图3.2修改后
四、运行结果及说明
图4.1.不存在安全序列
随机分配完资源后,进行安全检查,在检查过程中在屏幕上显示检查信息,上图为资源分配不安全时显示的信息。
图4.2.存在安全路径
存在安全路径后,在屏幕上显示变化过程和安全路径。
提示是否申请资源
图4.3.申请资源
提出申请后,询问进行随机分配资源还是手动分配
图4.4手动分配
图4.5.随机分配
五、实验总结
附录
#include
#include
#include
#defineM3
#defineN3
intNeed[M][N],Allocation[M][N],Avalible[N],Max[M][N],finish[N];
//Need:
进程需要的资源数Allocation:
进程已分配的资源;Avalible:
进程可供分配的资源
voiddisplay(int*a,intn)//显示一维数组
{inti;
for(i=0;iprintf("%3d",a[i]);
}
voiddisp()//显示资源列表
{inti,j,k,h,l;
printf("Nnumber\tMax\t\tneed\t\tallocation\tavalible\n");
for(i=0;i{printf("p%d\t",i);
display(Max[i],N);
printf("\t");
display(Need[i],N);
printf("\t");
display(Allocation[i],N);
printf("\t");
if(i==0)
display(Avalible,N);
printf("\n");
}}
intgrand(int*a,int*b,intn)//分配资源
{inti;
for(i=0;ia[i]=b[i];
}
intcheck(int*a,int*b,intn)//检查Allocation是否与Max相等
{inti;
for(i=0;i{if(a[i]
return1;
}
intcompare(int*a,int*b,intn)//比较数组的大小
{inti;
charflag;
for(i=0;i{if(a[i]
return0;
}
return1;
}
intcomp(int*a,int*b,intn,intm)//比较数组
{inti;
for(i=0;i{if(a[i]>b[i])
{if(m==1)
printf("requestNumber%dresoucehaveanerrorrequestoverflowavalible[%d]\n",i+1,i);
if(m==2)
printf("requestNumber%dresoucehaveanerrorrequestoverflowNeed[%d]\n",i+1,i);
return0;}}
return1;
}
voiddec(int*a,int*b,intn)//数组相减
{inti;
for(i=0;ia[i]-=b[i];
}
charinput()//输入数据
{charc;
c=getchar()-0x30;
returnc;
}
voidadd(int*a,int*b,intn,intm)//数组相加
{inti;
for(i=0;ia[i]+=b[i];
for(i=0;i{if(m==0)printf("Avalible[%d]=%d",i,a[i]);
if(m==3)printf("\n");
if(m==1)printf("workvaluesechangedwork[%d]=%d\n",i,a[i]);
}
printf("\n");
}
//检查安全序列
intsafe()
{inti,count=0,n,j,r1=1;
intwork[N],sr[M],flag;
intfinish1[N];
grand(work,Avalible,N);
printf("checksafelist......\n");
for(i=0;ifinish1[i]=-1;
for(n=0;n{for(i=0;i{flag=compare(work,Need[i],N);
if(flag==0){printf("can'tsatisfyprocess[%d]->need[%d]",n,i);break;}
if(finish1[i]==-1&&flag==1&&finish[i]==-1)
{printf("findarightneed----process[%d]->need[%d]\n",n,i);
add(work,Allocation[i],N,r1);
finish1[i]=1;sr[count]=i;
count++;//记录安全序列
}}}
if(count>=M)
{printf("-----haveansafelist-----\n");
for(i=0;i{if(i!
=M-1)
printf("p%d->",sr[i]);
else
printf("p%d\n",sr[i]);
}return1;}
else
{printf("afterchecktherenosafelist.....\n");
printf("can'tapplyresouce\n");
return0;
}}
//随机请求资源
intran_request()
{inti,flag1,flag2,r1=1,r2=2,r3=3;
intrequest[N],pn;
pn=rand()%2;
printf("Process[%d]callforresouce\n",pn);
for(i=0;irequest[i]=rand()%5;
for(i=0;ifinish[i]=-1;
printf("randomproducerequest[%d]:
",N);
display(request,N);
printf("\n");
if(finish[pn]==-1)//finish记录进程是否分配完成{
flag1=comp(request,Avalible,N,r1);
flag2=comp(request,Need[pn],N,r2);
if(flag1==1&&flag2==1)
{printf("callforrequestavalible");
dec(Avalible,request,N);
dec(Need[pn],request,N);
add(Allocation[pn],request,N,r3);
disp();
if(safe()==1)
{if(check(Allocation[pn],Max[pn],N)==1)
{add(Avalible,Allocation[pn],N,0);
finish[pn]=1;}
return1;}
else
return0;}}
else
printf("theresoucehaveassingned\n");
}
intrequest()//手动申请资源
{inti,j,pn,c,flag1,flag2,r1=1,r2=2,r3=3,k=0;
intrt[N];
printf("pleaseinputtheprocessnumberwhichyouwant:
");
scanf("%d",&pn);
if(pn>M-1)printf("inputerror!
!
");
else
{printf("\npleaseinputtherequestnumber:
\n");
for(i=0;i{getchar();
printf("The%drquest:
\n",i);
rt[i]=input();}
printf("Yourrequestis锛歕n");
display(rt,N);
if(finish[pn]==-1)
{flag1=comp(rt,Avalible,N,r1);
flag2=comp(rt,Need[pn],N,r2);
if(flag1==1&&flag2==1)
{printf("callforrequestavalible");
dec(Avalible,rt,N);
dec(Need[pn],rt,N);
add(Allocation[pn],rt,N,r3);
disp();
if(safe()==1)
{if(check(Allocation[pn],Max[pn],N)==1)
{add(Avalible,Allocation[pn],N,0);
finish[pn]=1;
k++;}
return1;}
elsereturn0;}}
else
printf("Theresoucehaveassigned\n");
}}
intmain()
{inti,j,s_flag;
charc,s;
intav[N],s_ll[M][N];
for(i=0;i{finish[i]=-1;}
srand(time(NULL));
for(i=0;ifor(j=0;j{Allocation[i][j]=rand()%10;
Need[i][j]=rand()%10;
Max[i][j]=Allocation[i][j]+Need[i][j];
}
for(i=0;i{Avalible[i]=rand()%12;}
disp();s_flag=safe();
if(s_flag==1)
{printf("是否申请资源---(Y/N)\n");
c=getchar();
if(c=='Y'||c=='y')
{
N1:
printf("1---------randomrequestresouce\n");
printf("2---------requestresoucebyman\n");
grand(av,Avalible,N);//保存原始的available的值
for(i=0;i{grand(s_ll[i],Allocation[i],N);}
getchar();
Mnu:
s=getchar();
switch(s)
{case'1':
if(ran_request()==1)
{printf("continuerequest(Y/N)\n");
getchar();c=getchar();
if(c=='Y'||c=='y')
gotoN1;}
else
{grand(Avalible,av,N);
for(i=0;igrand(Allocation[i],s_ll[i],N);}
break;
case'2':
if(request()==1){
printf("continuerequest(Y/N)\n");
getchar();c=getchar();
if(c=='Y'||c=='y')
gotoN1;}
else
{grand(Avalible,av,N);
for(i=0;igrand(Allocation[i],s_ll[i],N);}
break;
default:
printf("inputerror,pleaseinputagin...\n");gotoMnu;
}}
if(c=='N'||c=='n')
printf("Thankforyouruse....\n");}
return0;}