银行家算法.docx
《银行家算法.docx》由会员分享,可在线阅读,更多相关《银行家算法.docx(23页珍藏版)》请在冰豆网上搜索。
![银行家算法.docx](https://file1.bdocx.com/fileroot1/2022-12/7/a72dfcce-bdee-4309-9ae8-b37c01e7e8d7/a72dfcce-bdee-4309-9ae8-b37c01e7e8d71.gif)
银行家算法
银行家算法的模拟实现
1.课程设计题目
银行家算法的模拟实现。
应用银行家算法验证进程安全性检查及分配资源。
2.课程设计目的
本设计的目的是通过编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用适当的算法,有效地防止和避免死锁地发生。
了解进程产生死锁的原因,了解为什么要进行死锁的避免。
掌握银行家算法的数据结构,了解算法的执行过程,加深对银行家算法的理解。
3.课程设计的开发语言
C++编程语言
4.功能描述
A.输出资源分配情况
B.输出资源分配后后的情况
C.银行家算法:
设进程i提出请求Request[n],则银行家算法按如下规则进行判断。
(1)如果Request[n]>Need[i,n],则报错返回。
(2)如果Request[n]>Available,则进程i进入等待资源状态并返回。
(3)假设进程i的申请已获批准,于是修改系统状态:
Available=Available-Request
Allocation=Allocation+Request
Need=Need-Request
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
D.安全性检查
(1)设置两个工作向量Work=Available;Finish[M]=False
(2)从进程集合中找到一个满足下述条件的进程,
Finish[i]=False
Need<=Work
(3)如找到,执行(3);否则,执行(4)
设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work=Work+Allocation
Finish=True
GOTO2
(4)如所有的进程Finish[M]=true,则表示安全;
否则系统不安全。
5.方案论证
5.1.实验原理分析
5.1.1.算法的来源及基本思想
银行家算法,顾名思义是来源于银行的借贷业务,通过这个算法可以用来解决生活中的实际问题,如银行贷款等。
一定数量的本金要应多个客户的借贷周转,为了防止银行加资金无法周转而倒闭,对每一笔贷款,必须考察其是否能限期归还。
在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,必须保证得到的资源的进程能在有限的时间内归还资源,以供其他进程使用资源。
如果资源分配不得到就会发生进程循环等待资源,则进程都无法继续执行下去的死锁现象。
5.1.2.死锁产生的条件
银行家算法是用来避免死锁的一种重要方法,通过编写一个简单的银行家算法程序,加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
死锁的产生,必须同时满足四个条件:
A、即一个资源每次只能由一个进程使用;
B、第二个为等待条件,即一个进程请求资源不能满足时,它必须等待,单它仍继续宝石已得到的所有其他资源;
C、第三个为非剥夺条件,即在出现死锁的系统中一定有不可剥夺使用的资源;
D、第四个为循环等待条件,系统中存在若干个循环等待的进程,即其中每一个进程分别等待它前一个进程所持有的资源。
防止死锁的机构只能确保上述四个条件之一不出现,则系统就不会发生死锁。
银行家算法是避免死锁的方法中,施加的限制条件较弱的,有利于获得令人满意的系统性能的方法。
在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁。
5.1.3模拟进程申请资源
把一个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等待态和完成态。
当进程在处于等待态时,表示系统不能满足该进程当前的资源申请。
“资源需求总量”表示进程在整个执行过程中总共要申请的资源量。
显然,,每个进程的资源需求总量不能超过系统拥有的资源总数,银行算法进行资源分配可以避免死锁.
5.2.程序结构分析:
5.2.1.程序流程图
程序流程图是人们对解决问题的方法、思路或算法的一种描述。
流程图的优点:
(a)采用简单规范的符号,画法简单;
(b)结构清晰,逻辑性强;(c)便于描述,容易理解。
流程图采用规范的符号
(1)起始框
(2)终止框
(3)执行框(4)判别框
图1银行家算法流程图
6程序及说明
算法用到的主要数据结构和C语言说明。
(1)可利用资源向量INTAVAILABLE[M]M为资源的类型。
(2)最大需求矩阵INTMAX[N][M]N为进程的数量。
(3)已分配矩阵INTALLOCATION[N][M]
(4)还需求矩阵INTNEED[N]
假设有M个进程N类资源,则有如下数据结构:
#defineW10
#defineR20
intM;
intN;
intALL_RESOURCE[W];
intMAX[W][R];
intAVAILABLE[R];
intALLOCATION[W][R];
intNEED[W][R];
intRequest[R];
(5)各子模块相关函数代码已经在附录中一一列出。
6.1示例数据
进程数:
2
资源数:
2
资源0:
10
资源1:
20
资源0(最大需求)
资源1(最大需求)
进程0
0
1
进程1
10
20
资源0(已占有)
资源1(已占用)
进程0
0
0
进程1
6
8
7设计结果与分析
图2输入数据完成初始化
注:
初始化时,如果输入数据不符合要求,程序能给出错误提示并要求使用者重新输入数据。
为简便期间,省去此功能的截屏图像。
演示者可以自行上机体会。
计算机自动检测水所有进程能否构成一个安全序列。
图3手动为进程申请资源
如果能够构成安全序列,就显示出是否进行手动申请资源。
输入k开始手动申请资源。
图4申请资源的进程号
申请资源并进行安全性检查。
图5选择是否继续演示
用户根据根据该界面选择是否继续演示操作。
图6配置资源数
用户根据此界面进行配置相应的资源数目。
图7选择退出演示运行界面
用户输入输入N结束演示。
7.3出现问题及解决方案
源程序中未考虑进程状态会随着程序运行发生变化,为了完善程序专门编写了状态函数voidset()来显示进程状态。
如图6-2-2与图6-2-4倒数2、3行中均显示了进程状态。
源程序中指定资源数必须是三种,经过改进后资源数可以为1到10中的任意数。
源程序资源矩阵的输出界面不能自动适应数据长度的变化,修改后资源的矩阵输出界面中的数据显示获得了改善。
8.设计心得体会
这次课程设计没有将程序初始化代码段分离出来,以至于程序的结构不清晰,由于初始化代码不是一个独立的函数致使程序的可读性较差。
作课程设计时应尽量把功能模块设计好考虑好,使程序易于理解。
设计中得到了老师和广大同学的帮助,并参考了网络上的优秀论文和纸质文件,使我的课程设计能够较为顺利的进行下去。
9.附录(关键源代码)
#include"string.h"
#include"iostream"
#include"iomanip"
usingnamespacestd;
#defineFALSE0
#defineTRUE1
#defineW10
#defineR20
intFINISH[W];
intM;
intN;
intALL_RESOURCE[W];
intMAX[W][R];
intAVAILABLE[R];
intALLOCATION[W][R];
intNEED[W][R];
intRequest[R];
intWORK[100];
intQ[100];
intL=0;
voidshowdata()
{
inti,j;
cout<<"————————————————————————"<cout<<"各种资源的总数量(all):
"<cout<<"";
for(j=0;j"<cout<cout<<"系统目前各种资源可用的数为(available):
"<cout<<"";
for(j=0;j"<cout<cout<<"—————————————————————";
cout<<"各进程还需要的资源量(need):
"<cout<<"";
for(j=0;jfor(i=0;i{
cout<";
for(j=0;j}
cout<cout<<"—————————————————————";
cout<<"各进程已经得到的资源量(allocation):
"<cout<<"";
for(j=0;jfor(i=0;i{
cout<";
for(j=0;j}
cout<}
voidchangdata(intk)
{
intj;
for(j=0;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{AVAILABLE[j]=AVAILABLE[j]+Request[j];
ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j];
NEED[k][j]=NEED[k][j]+Request[j];
}
}
intchkerr(ints)
{intWORKrest;//FINISH[W]
inti,j,k=0;
for(i=0;ifor(j=0;j{
WORKrest=AVAILABLE[j];
i=s;
do
{
if(FINISH[i]==FALSE&&NEED[i][j]<=WORKrest)
{
WORKrest=WORKrest+ALLOCATION[i][j];
FINISH[i]=TRUE;
i=0;
}
else
{
i++;
}
}while(ifor(i=0;iif(FINISH[i]==FALSE)
{
cout<cout<<"系统不安全!
!
!
本次资源申请不成功!
!
!
"<cout<return1;
cout<<"进程p"<
阻塞"<}
}
cout<cout<<"经安全性检查,系统安全,本次分配成功。
"<cout<return0;
}
voidset()
{
intt[10];
for(inti=0;it[i]=0;
for(intj=0;j}
for(i=0;iif(t[i]==N)
{cout<<"进程p"<
运行结束"<for(intk=0;kAVAILABLE[k]=AVAILABLE[k]+ALLOCATION[i][k];
ALLOCATION[i][k]=0;
}
else
cout<<"进程p"<
等待调用"<}
voidsafe()
{cout<inti,j;
for(j=0;jWORK[j]=AVAILABLE[j];
intflag=0;
for(i=0;iFINISH[i]=FALSE;
for(i=0;i{
if(FINISH[i]==FALSE)
{
flag=0;
for(j=0;j{
if(WORK[j]>=NEED[i][j])
flag=flag+1;
else
break;
}
if(flag==N)
{
Q[L]=i;
FINISH[i]=TRUE;
for(j=0;j{
WORK[j]=WORK[j]+ALLOCATION[i][j];//cout<<"b"<}
L=L+1;//cout<cout<<"进程p"<
"<for(j=0;jcout<<""<<"资源"<"<cout<i=0;
}
}
else;
}
}
inttest()
{
if(L{
cout<<"\n当前状态不安全!
!
!
!
!
";
cout<<"不存在安全序列"<cout<<"^^^您不能向系统申请资源^^^"<cout<<"………计算机检测结束………"<return0;
}
else
{
inti;
//l=0;
cout<<"\n此时处于安全的状态!
!
!
"<cout<cout<<"安全序列是:
";
for(i=0;i{
cout<<"进程"<<"p"<";
FINISH[i]=FALSE;
}
cout<cout<<"………计算机检测结束………"<return1;
}
}
voidbank()
{
inti=0,j=0;
//i=0;intj=0;
charflag='Y';
while(flag=='Y'||flag=='y')
{
i=-1;
while(i<0||i>=M)
{cout<cout<<"请输入需申请资源的进程号(从P0到P"<):
";
cout<<"p";cin>>i;
if(i<0||i>=M)cout<<"输入的进程号不存在,重新输入!
"<}
cout<<"请输入进程P"<
"<for(j=0;j{
cout<<"资源"<";
cin>>Request[j];
if(Request[j]>NEED[i][j])
{
cout<<"进程P"<
";
cout<<"申请不合理,出错!
请重新选择!
"<flag='N';
break;
}
else
{
if(Request[j]>AVAILABLE[j])//若请求的资源数大于可用资源数
{
cout<<"进程P"<
";
cout<<"申请不合理,出错!
请重新选择!
"<flag='N';
break;
}
}
}
if(flag=='Y'||flag=='y')
{
changdata(i);
if(chkerr(i))
{
rstordata(i);
showdata();
}
else{
showdata();
set();
}
}
else
showdata();
cout<cout<<"是否继续银行家算法演示,按'Y'或'y'键继续,按'N'或'n'键退出演示:
";
cin>>flag;
}
}
voidmain()
{
cout<<"********************************"<cout<<"欢迎使用银行家安全性算法模拟程序"<cout<cout<<"本程序由C++编制完成"<cout<cout<<"********************************"<inti=0,j=0,p;
do{cout<<"请输入总进程数:
"<cin>>M;}while(M<0);
do{cout<<"请输入总资源种类:
"<cin>>N;}while(N<0);
cout<<"请输入总资源数(all_resource):
"<for(i=0;i{cout<<"资源"<
";cin>>ALL_RESOURCE[i];}
cout<<"依次输入各进程所需要的最大资源数量(max):
"<for(i=0;i{
for(j=0;j{
do
{
cout<<"进程"<
cout<";
cin>>MAX[i][j];
if(MAX[i][j]>ALL_RESOURCE[j])
cout<}while(MAX[i][j]>ALL_RESOURCE[j]);
}
}
cout<<"依次输入各进程已经占据的资源数量(allocation):
"<for(i=0;i{
for(j=0;j{
do
{cout<<"进程"<
cout<";
cin>>ALLOCATION[i][j];
if(ALLOCATION[i][j]>MAX[i][j])
cout<}while(ALLOCATION[i][j]>MAX[i][j]);
}
}
for(j=0;j{p=ALL_RESOURCE[j];
for(i=0;i{
p=p-ALLOCATION[i][j];
AVAILABLE[j]=p;
if(AVAILABLE[j]<0)
AVAILABLE[j]=0;
}
}
for(i=0;ifor(j=0;jNEED[i][j]=MAX[i][j]-ALLOCATION[i][j];
safe();
if(test()==0);
{}
else{
charletter;
cout<";
cin>>letter;
if(letter=='k')
{showdata();
bank();};
};
}
10.参考文献
[1]汤子赢《计算机操作系统(修订版)》[M].西安:
电子科技大学出版社2006:
20-100
[2]屠立德《操作系统基础(第三版)》[M].北京:
清华大学出版社2000:
34-50
[3]庞丽萍《操作系统原理》[M].武汉:
华中科技大学出版社2000:
55-120
[4]曹聪,范廉明.《操作系统原理与分析》[M].北京:
科学出版社2003:
1-100