银行家死锁避免算法模拟
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
银行家死锁防止算法模拟之迟辟智美创作
一.课程设计目的
通过本次实验掌握银行家死锁防止算法的基本思想.当进程提出资源申请时,能够用该算法判断是否拒绝进程请求.二.课程设计摘要
银行家算法:
我们可以把把持系统看作是银行家,把持系统管理的资源相当于银行家管理的资金,进程向把持系统请求分配资源相当于用户向银行家存款.把持系统依照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最年夜需求量,如果系统现存的资源可以满足它的最年夜需求量则按以后的申请量分配资源,否则就推迟分配.当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超越了该进程对资源的最年夜需求量.若超越则拒绝分配资源,若没有超越则再测试系统现存的资源能否满足该进程尚需的最年夜资源量,若能满足则按以后的申请量分配资源,否则也要推迟分配.
四.课程设计原理分析
在多道法式系统中,虽可借助于多个进程的并发执行,来改善系统的资源利用率,提高系统的吞吐量,但可能发生一种危险——死锁.所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵局状态时,若无外力作用,它们都将无法再向前推进.为保证系统中诸进程的正常运行,应事先采用需要的办法,来预防死锁.最有代表性的防止死锁的方法,是Dijkstra的银行家算法.
死锁:
死锁的发生,必需同时满足四个条件,第一个为互斥条件,即一个资源每次只能由一个进程占用;第二个为请求和坚持条件,指进程已经坚持了至少一个资源,但又提出了新的资源请求,而该资源又被其他进程占有,此时请求进程阻塞,但又对自己已获得的其他资源坚持不放;第三个为非剥夺条件,即在呈现死锁的系统中一定有不成剥夺使用的资源;第四个为循环等候条件,系统中存在若干个循环等候的进程,即其中每一个进程分别等候它前一个进程所持有的资源.防止死锁的机构只能确保上述四个条件之一不呈现,则系统就不会发生死锁.
银行家算法原理:
银行家算法是防止死锁的一种重要方法,通过编写一个简
单的银行家算法法式,加深了解有关资源申请、防止死锁等概念,并体会和了解死锁和防止死锁的具体实施方法.通过这个算法可以用来解决生活中的实际问题,如银行存款等.
银行家算法,顾名思义是来源于银行的借贷业务,一定命量的本金要应多个客户的借贷周转,为了防止银行家资金无法周转而开张,对每一笔存款,必需考察其是否能限期归还.在把持系统中研究资源分配战略时也有类似问题,系统中有限的资源要供多个进程使用,必需保证获得的资源的进程能在有限的时间内归还资源,以供其他进程使用资源.如果资源分配不获得就会发生进程循环等候资源,则进程都无法继续执行下去的死锁现象.把一个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等候态和完成态.当进程在处于等候态时,暗示系统不能满足该进程以后的资源申请.“资源需求总量”暗示进程在整个执行过程中总共要申请的资源量.显然,,每个进程的资源需求总量不能超越系统拥有的资源总数, 银行算法进行资源分配可以防止死锁.
算法思想:
将一定命量的资金供多个用户周转使用,当用户对资金的最年夜申请量不超越现存资金时可接纳一个新客户,客户可以分期借款,但借款总数不能超越最年夜的申请量.银
行家对客户的借款可以推迟支付,可是能够使客户在有限
的时间内获得借款,客户获得所有的借款后能在有限的时
间内归还.
用银行家算法分配资源时,测试进程对资源的最年夜需求量,若现存资源能满足最年夜需求就满足以后进程的申
请,否则推迟分配,这样能够保证至少有一个进程可以获
得所需的全部资源而执行到结束,然后归还资源,若OS能保证所有进程在有限的时间内获得所需资源则称系统处于
平安状态.
五.算法实现
1.法式流程图:
2.算法描述:
银行家算法的设计思想是:当用户申请一组资源时,系
统必需做出判断;如果把这些资源分出去,系统是否还处
于平装置他.若是,就可以分出这些资源;否则,该申请暂不能满足.
3.数据结构描述:(n暗示系统中进程的数目,m暗示资源的分类数.)
3.1. Available是一个长度为m的向量,它暗示每类资源可用的数量.Available [j]=k,暗示rj类资源可用的数量为k. 3.是一个n×m矩阵,它暗示每个进程对资源的最年夜需求.Max [i,j]=k,暗示进程pi至多可以申请k个rj类资源单元.
3.是一个n×m矩阵,它暗示以后分给每个进程的资源数目.Allocation [i,j]=k,暗示进程pi以后分到k个rj类资源.
3.4. Need是一个n×m矩阵,它暗示每个进程还缺少几多资源.Need[i,j]=k,暗示进程pi尚需k个rj类资源才华完成其任务.显然Need[i,j]= Max [i,j]- Allocation [i,j].
这些数据结构的年夜小和数值随时间推移而改变.
4.系统所执行的平安性算法描述如下:
4.1.设置2个向量:工作向量Work:它暗示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行平安算法开始时,Work = Available.
Finish[i] :它暗示系统是否有足够的资源分配给进程,使之完成运行.开始时先做Finish[i]=true.
4.2.从进程集合中找到一个满足下述条件的进程:
Finish[i]=flase;Need[i,j]≤Work[j];若找到,则执行步伐3,否则,执行步伐4.
4.3.当进程pi获得资源后,可顺利执行,直至完成,并释放分配给它的资源.
4.4.如果所有进程的Finish[i]=true都满足.则暗示系统处于平安状态;否则,系统处于不服安状态.
#include<iostream>
#include<string>
#include<stdio.h>
using namespace std;
#define False 0
#define True 1
int Max[100][100]={0};//各进程所需各类资源的最年夜需求
int Avaliable[100]={0};//系统可用资源
char name[100]={0};//资源的名称
int Allocation[100][100]={0};//系统已分配资源
int Need[100][100]={0};//还需要资源
int Request[100]={0};//请求资源向量
int temp[100]={0};//寄存平安序列
int Work[100]={0};//寄存系统可提供资源
int M=100;//作业的最年夜数为100
int N=100;//资源的最年夜数为100
void showdata()//显示资源矩阵
{
int i,j;
cout<<"系统目前可用的资源[Avaliable]:"<<endl;
for(i=0;i<N;i++)
cout<<name[i]<<" ";
cout<<endl;
for (j=0;j<N;j++)
cout<<Avaliable[j]<<" ";//输出分配资源
cout<<endl;
cout<<" Max Allocation Need"<<endl; cout<<"进程名 ";
for(j=0;j<3;j++){
for(i=0;i<N;i++)
cout<<name[i]<<" ";
cout<<" ";
}
cout<<endl;
for(i=0;i<M;i++){
cout<<" "<<i<<" ";
for(j=0;j<N;j++)
cout<<Max[i][j]<<" ";
cout<<" ";
for(j=0;j<N;j++)
cout<<Allocation[i][j]<<" ";
cout<<" ";
for(j=0;j<N;j++)
cout<<Need[i][j]<<" ";
cout<<endl;
}
}
int changdata(int i)//进行资源分配
{
int j;
for (j=0;j<M;j++) {
Avaliable[j]=Avaliable[j]-Request[j];
Allocation[i][j]=Allocation[i][j]+Request[j]; Need[i][j]=Need[i][j]-Request[j];
}
return 1;
}
int safe()//平安性算法
{
int i,k=0,m,apply,Finish[100]={0};
int j;
int flag=0;
Work[0]=Avaliable[0];
Work[1]=Avaliable[1];
Work[2]=Avaliable[2];
for(i=0;i<M;i++){
apply=0;
for(j=0;j<N;j++){
if (Finish[i]==False&&Need[i][j]<=Work[j]){ apply++;
if(apply==N){
for(m=0;m<N;m++)
Work[m]=Work[m]+Allocation[i][m];//变分配数 Finish[i]=True;
temp[k]=i;
i=-1;
k++;
flag++;
}
}
}
}
for(i=0;i<M;i++){
if(Finish[i]==False){
cout<<"系统不服安"<<endl;//不胜利系统不服安
return -1;
}
}
cout<<"系统是平安的!"<<endl;//如果平安,输出胜利 cout<<"分配的序列:";
for(i=0;i<M;i++){//输出运行进程数组
cout<<temp[i];
if(i<M-1) cout<<"->";
}
cout<<endl;
return 0;
}
void share()//利用银行家算法对申请资源对进行判定
{
char ch;
int i=0,j=0;
ch='y';
cout<<"请输入要求分配的资源进程号(0-"<<M-1<<"):"; cin>>i;//输入须申请的资源号
cout<<"请输入进程 "<<i<<" 申请的资源:"<<endl;
for(j=0;j<N;j++)
{
cout<<name[j]<<":";
cin>>Request[j];//输入需要申请的资源
}
for (j=0;j<N;j++){
if(Request[j]>Need[i][j])//判断申请是否年夜于需求,若年夜于则犯错
{
cout<<"进程 "<<i<<"申请的资源年夜于它需要的资源";
cout<<" 分配分歧理,不予分配!"<<endl;
ch='n';
break;
}
else {
if(Request[j]>Avaliable[j])//判断申请是否年夜于以后资源,若年夜于则
{ //犯错
cout<<"进程"<<i<<"申请的资源年夜于系统现在可利用的资源";
cout<<" 分配犯错,不予分配!"<<endl;
ch='n';
break;
}
}
}
if(ch=='y') {
changdata(i);//根据进程需求量变换资源
showdata();//根据进程需求量显示变换后的资源
safe();//根据进程需求量进行银行家算法判断
}
}
void addresources(){//添加资源
int n,flag;
cout<<"请输入需要添加资源种类的数量:"; cin>>n;
flag=N;
N=N+n;
for(int i=0;i<n;i++){
cout<<"名称:";
cin>>name[flag];
cout<<"数量:";
cin>>Avaliable[flag++];
}
showdata();
safe();
}
void changeresources(){//修改资源函数
cout<<"系统目前可用的资源[Avaliable]:"<<endl; for(int i=0;i<N;i++)
cout<<name[i]<<":"<<Avaliable[i]<<endl; cout<<"输入系统可用资源[Avaliable]:"<<endl;
cin>>Avaliable[0]>>Avaliable[1]>>Avaliable[2]; cout<<"经修改后的系统可用资源为"<<endl; for (int k=0;k<N;k++)
cout<<name[k]<<":"<<Avaliable[k]<<endl; showdata();
safe();
}
void delresources(){//删除资源
char ming;
int i,flag=1;
cout<<"请输入需要删除的资源名称:";
do{
cin>>ming;
for(i=0;i<N;i++)
if(ming==name[i]){
flag=0;
break;
}
if(i==N)
cout<<"该资源名称不存在,请重新输入:"; }
while(flag);
for(int j=i;j<N-1;j++)
{
name[j]=name[j+1];
Avaliable[j]=Avaliable[j+1];
}
N=N-1;
showdata();
safe();
}
void addprocess(){//添加作业
int flag=M;
M=M+1;
cout<<"请输入该作业的最年夜需求量[Max]"<<endl; for(int i=0;i<N;i++){
cout<<name[i]<<":";
cin>>Max[flag][i];
Need[flag][i]=Max[flag][i]-Allocation[flag][i];
}
showdata();
safe();
}
int main()//主函数
{
int i,j,number,choice,m,n,flag;
char ming;
cout<<"*****************资源管理系统的设计与实现*****************"<<endl;
cout<<"请首先输入系统可供资源种类的数量:"; cin>>n;
N=n;
for(i=0;i<n;i++)
{
cout<<"资源"<<i+1<<"的名称:";
cin>>ming;
name[i]=ming;
cout<<"资源的数量:";
cin>>number;
Avaliable[i]=number;
}
cout<<endl;
cout<<"请输入作业的数量:";
cin>>m;
M=m;
cout<<"请输入各进程的最年夜需求量
("<<m<<"*"<<n<<"矩阵)[Max]:"<<endl;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
cin>>Max[i][j];
do{
flag=0;
cout<<"请输入各进程已经申请的资源量
("<<m<<"*"<<n<<"矩阵)[Allocation]:"<<endl;
for(i=0;i<m;i++)
for(j=0;j<n;j++){
cin>>Allocation[i][j];
if(Allocation[i][j]>Max[i][j])
flag=1;
Need[i][j]=Max[i][j]-Allocation[i][j];
}
if(flag)
cout<<"申请的资源年夜于最年夜需求量,请重新输入!\n";
}
while(flag);
showdata();//显示各种资源
safe();//用银行家算法判定系统是否平安
while(choice)
{
cout<<"**************银行家算法演示
***************"<<endl;
cout<<" 1:增加资源 "<<endl;
cout<<" 2:删除资源 "<<endl;
cout<<" 3:修改资源 "<<endl;
cout<<" 4:分配资源 "<<endl;
cout<<" 5:增加作业 "<<endl;
cout<<" 0:离开 "<<endl;
cout<<"****************************************** *"<<endl;
cout<<"请选择功能号:";
cin>>choice;
switch(choice)
{
case 1: addresources();break;
case 2: delresources();break;
case 3: changeresources();break;
case 4: share();break;
case 5: addprocess();break;
case 0: choice=0;break;
default: cout<<"请正确选择功能号(0-5)!"<<endl;break; }
}
return 1;
}
调试及运行结果:
检测结果如下:
1.假设系统只有一种资源a,剩余数量为2,分配情况如下:
2.假设系统只有一种资源a,剩余数量为2,分配情况如下:
注:“系统不服安”暗示此种情况是银行家算法也解不了的死锁.
3.假设系统有2种资源a,b,a的剩余数量为4,b的剩余数量为3,分配情况如下:
通过本次试验,加深了自己对死锁问题和银行家算法的理解.
对银行家算法的思想有了更加深刻的认识,而且意识到银行家算法其实不是能防止所有的死锁,可以称这种情况为潜在的死锁.。