操作系统实验银行家算法.docx
《操作系统实验银行家算法.docx》由会员分享,可在线阅读,更多相关《操作系统实验银行家算法.docx(27页珍藏版)》请在冰豆网上搜索。
操作系统实验银行家算法
学号P7*******专业计算机科学与技术姓名
实验日期2017.11.9教师签字成绩
实验报告
【实验名称】银行家算法
【实验目的】
掌握银行家算法,用银行家算法模拟操作系统避免死锁的方法
【实验原理】
银行家算法又称“资源分配拒绝”法,其基本思想是,系统中的所有进程放入进程集合,在安全状态下系统受到进程的请求后试探性的把资源分配给他,现在系统将剩下的资源和进程集合中其他进程还需要的资源数做比较,找出剩余资源能满足最大需求量的进程,从而保证进程运行完成后还回全部资源。
这时系统将该进程从进程集合中将其清除。
此时系统中的资源就更多了。
反复执行上面的步骤,最后检查进程的集合为空时就表明本次申请可行,系统处于安全状态,可以实施本次分配,否则,只要进程集合非空,系统便处于不安全状态,本次不能分配给他。
请进程等待
用C语言编写一个简单的银行家算法模拟程序,用银行家算法实现资源分配。
程序能模拟多个进程共享多种资源的情形。
进程可动态地申请资源,系统按各进程的申请动态地分配资源。
要求程序具有显示和打印各进程的某一时刻的资源分配表和安全序列;显示和打印各进程依次要求申请的资源数量以及为某进程分配资源后的有关资源数据的情况
【数据结构和符号说明】
可利用资源向量Available
最大需求矩阵Max
分配矩阵Allocation
需求矩阵Need
工作向量Work
标记向量Finish
charname[100][10];//定义最大100个进程,每个大小为10
intMax[100][100];//定义
intAllocation[100][100];//可利用资源向量资源数
intNeed[100][100];//需求矩阵
intavaiable[100];//系统可利用资源
intavaiable1[100];
intstate[100];//进程状态数组
charname1[100][10];//进程名
intbigger;;//是否大于
intN;//进程数
intn;//资源数
intcounter;
函数:
voidInput()//输入函数
voidInit()//初始化
voidoutput()//输出安全序列或等待
voidinsert_pcb()//请求进程或更新进程
voidshow()//显示界面与选择intCmpRequestAvailable(intPos,intn)//比较Request和Available的大小
intCmpRequestNeed(intPos,intn)//比较Request和Need的大小
voidReset(intn,intPos)//更新request之后的Need,Allocation,Available的值voidBanker()//银行家算法
【实验流程图及算法实现】
用C语言编写一个简单的银行家算法模拟程序,用银行家算法实现资源分配。
程序能模拟多个进程共享多种资源的情形。
进程可动态地申请资源,系统按各进程的申请动态地分配资源。
要求程序具有显示和打印各进程的某一时刻的资源分配表和安全序列;显示和打印各进程依次要求申请的资源数量以及为某进程分配资源后的有关资源数据的情况
【流程图】
代码:
#include
usingnamespacestd;
charname[100][10];定义最大100个进程,每个大小为10
intMax[100][100];//定义
intAllocation[100][100];//可利用资源向量资源数
intNeed[100][100];//需求矩阵
intavaiable[100];//
intstate[100];//进程状态数组
intdayu;;是否大于
intN;
intn;
voidinput()
{
cout<<"输入进程个数"<cin>>N;
cout<<"输入资源个数"<cin>>n;
cout<<"系统现有的各资源的个数"<for(inti=0;icin>>avaiable[i];
for(inti=0;i{
cout<<"输入第"<
cin>>name[i];
cout<<"输入第"<
for(intj=0;jcin>>Max[i][j];
cout<<"输入第"<
for(intj=0;jcin>>Allocation[i][j];
state[i]=0;
}
for(inti=0;ifor(intj=0;jNeed[i][j]=Max[i][j]-Allocation[i][j];
}
voidyinhangjia()
{
inti,j,k;
for(i=0;i{
for(j=0;j{
if(state[j]==1)
continue;
dayu=0;
for(k=0;k{
if(avaiable[k]>=Need[j][k])
dayu=1;
else
{
dayu=0;
break;
}
}
if(dayu==1)//判断状态
{
state[j]=1;
cout<for(intm=0;mavaiable[m]+=Allocation[j][m];
break;
}
}
}
}
intmain()
{
input();//输入
yinhangjia();
}
截图:
带有resquest请求更新的银行家算法:
描述:
1)如果Request[i] 是进程Pi的请求向量,如果Request[i,j]=K,表示进程Pi需要K个Rj类型的资源。
当发出资源请求后,系统按下述步骤进行检查:
如果Requesti[j]<= Need[i,j],便转向步骤2;否则认为出错,因为它所需要的资源数已超过它所宣布的最大值。
2)如果Requesti[j]<=Available[j],便转向步骤3,否则,表示尚无足够资源,进程Pi须等待。
3)系统试探着把资源分配给进程,并修改下面数据结构中的数值。
4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。
若安全,才正式将资源分配给进i,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程等待。
流程图:
代码:
#include
#include
usingnamespacestd;
charname[100][10];//定义最大100个进程,每个大小为10
intMax[100][100];//定义
intAllocation[100][100];//可利用资源向量资源数
intNeed[100][100];//需求矩阵
intavaiable[100];//
intavaiable1[100];
intstate[100];//进程状态数组
charname1[100][10];
intbigger;;//是否大于
intN;
intn;
intcounter;
voidinput()//输入函数
{
cout<<"输入进程个数"<cin>>N;
cout<<"输入资源个数"<cin>>n;
cout<<"系统现有的各资源的个数"<for(inti=0;i{
cin>>avaiable[i];
avaiable1[i]=avaiable[i];
}
for(inti=0;i{
cout<<"输入第"<
cin>>name[i];
cout<<"输入第"<
for(intj=0;jcin>>Max[i][j];
cout<<"输入第"<
for(intj=0;jcin>>Allocation[i][j];
state[i]=0;
}
for(inti=0;ifor(intj=0;jNeed[i][j]=Max[i][j]-Allocation[i][j];
}
voidBanker()//银行家算法
{
inti,j,k;
counter=0;
for(i=0;istate[i]=0;
for(i=0;i{
for(j=0;j{
if(state[j]==1)
continue;
bigger=0;
for(k=0;k{
if(avaiable[k]>=Need[j][k])//每一个大于需求
bigger=1;
else
{
bigger=0;
break;//跳出需求循环
}
}
if(bigger==1)//判断状态,此时该进程所有need<=avaiable
{
state[j]=1;
strcpy(name1[counter++],name[j]);
for(k=0;kavaiable[k]+=Allocation[j][k];//更新avaiable向量
break;
}
}
}
}
voidoutput()//输出安全序列或等待
{
inti;
if(counter==N)
{
cout<<"安全序列为:
";
for(i=0;icout<";
cout<}
elsecout<<"不存在安全序列,插入失败"<}
voidinsert_pcb()//请求进程或更新进程
{
charname1[10];
intchoose;
intadd[100];
cout<<"1、增加新的进程"<cout<<"2、对原有进程增加资源申请"<cin>>choose;
if(choose==1)
{
intbigger=0;
cout<<"输入插入进程的名字"<cin>>name[N];
cout<<"输入该进程拥有的资源个数"<for(intj=0;jcin>>Allocation[N][j];
state[N]=0;
cout<<"输入该所需要各资源最大数目"<for(intj=0;j{
cin>>Max[N][j];
Need[N][j]=Max[N][j]-Allocation[N][j];
}
state[N]=0;
for(intk=0;k{
if(avaiable[k]>=Need[N][k])//每一个大于需求
bigger=1;
else
{
bigger=0;
break;//跳出需求循环
}
}
if(bigger==1)
{
cout<<"插入成功"<N=N+1;
Banker();
output();
}
else
cout<<"插入失败,进程等待!
"<}
else
{
intpos;//找到需更新进程的位置
cout<<"输入原有进程的名字"<cin>>name1[10];
for(inti=0;iif(!
strcmp(name1,name[i]))
{
pos=i;
break;
}
cout<<"输入该进程还需要的各资源数"<for(intj=0;jcin>>add[j];
for(intk=0;k{
if(avaiable[k]>=add[k])//每一个大于需求
bigger=1;
else
{
bigger=0;
break;//跳出需求循环
}
}
if(bigger==1)
{
cout<<"插入成功"<for(intm=0;m{
Max[pos][m]+=add[m];
Need[pos][m]+=add[m];
avaiable[m]=avaiable1[m];
}
Banker();
output();
}
elsecout<<"插入失败,进程等待!
"<}
}
voidshow()//显示界面与选择
{
inti,j;
cout<cout<<"进程名\t";
for(i=0;icout<<"max["<
cout<for(i=0;i{
cout<for(j=0;jcout<cout<}
cout<<"***************************************************"<cout<<"****************各进程已有资源数**********************"<cout<<"进程名\t";
for(i=0;icout<<"Allocation["<
cout<for(i=0;i{
cout<for(j=0;jcout<cout<}
cout<<"***************************************************"<cout<<"****************各进程需求资源数**********************"<cout<<"进程名\t";
for(i=0;icout<<"Need["<
cout<for(i=0;i{
cout<for(j=0;jcout<cout<}
cout<<"***************************************************"<}
intmain()
{
intselect;
cout<<"银行家算法"<cout<<"初始化"<input();//输入
show();
Banker();
output();
do
{
cout<<"1、更新"<cout<<"2、查看各进程的信息"<cout<<"3、结束"<cin>>select;
if(select==3)
break;
elseif(select==1)
insert_pcb();
elseshow();
}
while
(1);
}
截图:
输入资源种类数目,输入最大需求矩阵,输入分配矩阵,输入可用资源数目,得到安全序列
对进程P1进行请求,此时会形成一个新的安全序列,p1进程的need和max发生相应的变化。
继续修改进程4,插入各需求330,不存在安全序列,此时需要等待。
请求一个新进程,所需求的最大资源为334,现有为223,形成新的安全序列。
查看各进程信息,并输出安全序列。
再请求一个新的大进程,此时资源不足,需要等待。
资源数为4:
更新P1进程,程序阻塞,进程等待。
请求一个新进程,P5。
插入成功,此时有安全序列。
【小结或讨论】
1、银行家算法名字源于该算法实际上是用于确保银行系统不会用尽系统资源,因为当银行系统不再满足所有客户的需求,系统将不会分配钱(看作资源)给客户,银行必须确保对钱的请求不会导致银行系统处于不安全状态。
如果上述情况不会发生,则该情况下请求是被允许的,否则,客户必须等到其他客户往银行存进足够银行分配的资金。
2、银行家算法就是当接收到一个系统资源的分配后找到一个安全序列,使得进程间不会发生死锁,若发生死锁则让进程等待。
这次实验的核心问题在于试探分配,若试探分配得到的结果是系统不安全则分配作废,恢复原先资源分配状态,转而寻找其他可能的安全序列,只要找到一个安全序列即可结束程序,请求向量也被认定是安全的。
若遍历了所有的可能序列都不安全,则请求向量也就是不安全的。
2、银行家算法中有两处涉及到进程“等待”,一处是当请求资源小于可利用资源的时候,还有一处是安全性算法判断出系统不安全的时候。
在安全性检查的函数中调用银行家算法的函数需要注意初始化Work等向量。
3、银行家算法名字源于该算法实际上是用于确保银行系统不会用尽系统资源,因为当银行系统不再满足所有客户的需求,系统将不会分配钱(看作资源)给客户,银行必须确保对钱的请求不会导致银行系统处于不安全状态。
如果上述情况不会发生,则该情况下请求是被允许的,否则,客户必须等到其他客户往银行存进足够银行分配的资金。
4、同其他的算法相似,银行家算法运行时也有一些局限。
特别是,必须知道每个进程所能请求的资源。
在大多数系统,该信息是不可知的,使的无法顺利运行银行家算法。
而且也无法去假设进程数量是不变的,因为大多数的系统的进程数量是动态变化的。
再者,对于正确的算法,进程会释放其全部的资源(当进程结束运行),然而对于实际中的系统则是不可行。
为了资源的释放等上数小时甚至几天,通常是不可接受的。
5、通过本次实验,我对于银行家算法有了一定的认识,了解了死锁产生的基本条件。
对死锁的产生有了更加深刻的体会,同时掌握了解决死锁的银行家算法的基本思想。