银行家算法实验报告 2.docx
《银行家算法实验报告 2.docx》由会员分享,可在线阅读,更多相关《银行家算法实验报告 2.docx(22页珍藏版)》请在冰豆网上搜索。
银行家算法实验报告2
一.绪论
这次课程设计要求完成一个资源管理系统,该系统必须包括资源的添加、删除和修改等功能,并且允许其它进程来申请这里的资源,任何一个进程来申请资源时,必须先登记该进程对资源的申请要求,然后由系统检查当前资源的状况,并用银行家算法和安全性算法来检查是否允许分配资源给进程。
通过课程设计,加深我们对利用银行家算法避免死锁的理解。
在设计中主要的难点是用语言编写银行家算法和安全性算法,使系统资源分配能安全进行,避免系统死锁。
二.设计目的
在多道程序系统中,虽可借助于多个进程的并发执行,来改善系统的资源利用提高吞吐量,但可能发生一种危险——死锁。
所谓死锁,是指多个进程运行中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,他们都无法再向前推进。
虽然进程在运行过程中,可能发生死锁,但死锁的发生必须同时具备四个条件:
互斥条件、请求和保持条件、不剥夺条件、环路等待条件;防止死锁的机构只须确保上述四个条件之一不出现,则系统不会发生死锁。
系统的状态分为安全状态和不安全状态,只要能使系统都处于安全状态,便可避免死锁。
所谓安全状态,是指系统能按某种进程顺序(P1,P2,…,Pn),来为每个进程Pi分配其所需分配,直至满足每个进程对资源的最大需求,使每个进程都可顺利地完成。
如果系统无法找到一个这样地安全系列,则称系统处于不安全状态。
在操作系统中研究资源分配策略时也有类似的问题,系统中有限的资源要供多个进程使用,必须保证得到资源的进程能在有限的时间内归还资源,以供它进程使用资源。
如果资源分配不得当就会发生进程循环等待资源,各进程都无法继续执行下去的死锁现象。
而最有代表性的避免死锁的算法,是Dijkstra的银行家算法。
银行家算法是避免死锁的一种重要方法,在课程设计中用C语言编写一个资源管理系统,并要用银行家算法和安全性算法检查是否允许分配资源给进程,避免死锁。
通过课程设计,加深我们对了解有关资源申请、避免死锁等概念,并加深我们对银行家算法理解。
提高了我们分析、解决问题的能力。
三.设计要求
用所学过的语言编程实现一个资源管理系统,该系统必须包括资源的添加、删除和修改等功能,并且允许其它进程来申请这里的资源,任何一个进程来申请资源时,必须先登记该进程对资源的申请要求,然后由系统检查当前资源的状况,并用银行家算法和安全性算法来检查是否允许分配资源给进程。
四.原理分析
在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。
银行家算法是避免死锁的一种重要方法,为实现银行家算法,系统必须设置若干数据结构。
4.1、银行家算法中的数据结构
1)可利用资源向量Available
是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。
如果Available[j]=K,则表示系统中现有Rj类资源K个。
2)最大需求矩阵Max
这是一个n×m的矩阵,它定义了系统中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个,方能完成其任务。
Need[i,j]=Max[i,j]-Allocation[i,j]
4.2、银行家算法
设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。
当Pi发出资源请求后,系统按下述步骤进行检查:
如果Requesti[j]≤Need[i,j],便转向步骤2;否则认为出错,因为它所需要的资源数已超过它所宣布最大值。
1)如果Requesti[j]≤Available[j],便转向步骤(3);否则,表示尚无足够资源,Pi须等待。
2)系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值:
Available[j]∶=Available[j]-Requesti[j];
Allocation[i,j]∶=Allocation[i,j]+Requesti[j];
Need[i,j]∶=Need[i,j]-Requesti[j];
3)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。
若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待。
4.3、安全性算法
1)设置两个向量:
工作向量Work:
它表示系统可提供给进程继续运行所需的各类资源数目,它含有m个元素,在执行安全算法开始时,Work∶=Available;
工作向量Finish:
它表示系统是否有足够的资源分配给进程,使之运行完成。
开始时先做Finish[i]∶=false;当有足够资源分配给进程时,再令Finish[i]∶=true。
2)从进程集合中找到一个能满足下述条件的进程:
Finish[i]=false;
Need[i,j]≤Work[j];若找到,执行(3),否则,执行(4)
3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
Work[j]∶=Work[i]+Allocation[i,j];
Finish[i]∶=true;
gotostep2;
4)如果所有进程的Finish[i]=true都满足,则表示系统处于安全状态;否则,系统处于不安全状态
五.具体设计和程序流程图
在程序中设计五个进程,分别为pr0,pr1,pr2,pr3,pr4。
共享三类资源。
在这个资源管理系统中对进程的所需最大资源(Max)、已分配给当前进程资源(Allocation)和系统可用资源(Available)分别进行了初始化了值。
进程可动态地申请资源和释放资源,系统按各进程的申请动态地分配资源。
要求程序具有显示和打印各进程的某一时刻的资源分配表和安全序列,若分配不安全,则释放分配的资源,防止使系统进入不安全状态。
显示和打印各进程依次要求申请的资源号以及为某进程分配资源后的有关资源数据。
程序还可以实现对系统的修改。
如果修改系统可用资源(Available),和进程分配资源。
程序具体的设计是:
函数voidshowdata()用来显示资源矩阵,包括系统可用资源数目,进程对资源最大需求数,系统已分配给进程的资源数,进程还需求资源。
通过以上显示,很直观的观察到资源分配和修改的过程。
函数share()用来利用银行家算法对某个进程申请资源对进行判定。
函数intchangdata(inti)用来实现资源试探分配。
主要执行的步骤是Avaliable[j]=Avaliable[j]-Request[j],Allocation[i][j]=Allocation[i][j]+Request[j],Need[i][j]=Need[i][j]-
Request[j]。
函数safe()用来实现安全性算法,对分配后的资源进行计算,若分配资源后,系统是安全的,则资源完成本次分配。
若不安全将本次的试探分配作废,调用shifang()函数恢复原来的资源分配状态。
资源修改功能用Revision()来实现。
六.程序源代码
#include
#defineMM50
#definetrue1
#definefalse0
intav[MM];
intmax[MM][MM];
intal[MM][MM];
intneed[MM][MM];
intp[MM];/*进程*/
intN,M;/*进程数和资源数*/
ints(intav[MM],intneed[][MM],intal[][MM])/*安全性检查*/
{
inti,j,t=0,x,y=0,work[MM],finish[MM],pp[MM];
for(i=0;ifinish[i]=false;
for(j=0;jwork[j]=av[j];
for(x=0;x{
for(i=0;i{
for(j=0;j{
if(finish[i]==false&&(work[j]>=need[i][j]))
y++;/*y表示符合的资源个数*/
elsey=0;
if(y==M)/*如果第i个进程的所有资源都满足,分配并回收资源*/
{for(j=0;jwork[j]=work[j]+al[i][j];
finish[i]=true;
pp[t]=i;
t++;
y=0;
}
}/*第三个for*/
}/*第二个for*/
}/*第一个for*/
if(t==N)/*被分配的资源为N,安全*/
{
printf("\nitissafe!
!
\n");
printf("thesafeline:
\n");/*寻找安全序列*/
for(i=0;i{
printf("P[%d]",pp[i]);
}
returntrue;
}
else
if(t{
printf("\nitisunsafe!
!
\n");
returnfalse;
}
}
intf(intflag)/*请求资源*/
{
inti,j,k=0,r,y,request[MM];
while(flag)
{
printf("Inputwhichprocesssendarequest;\n");
scanf("%d",&i);
if(i>=N||i<0)
{
printf("theprocessdoesnotexist!
\n");
continue;
}
printf("inputthenumberofrequest;\n");
for(j=0;j{
scanf("%d",&request[j]);
}
for(j=0;j{
if(request[j]<=need[i][j]&&request[j]<=av[j])/*试探着分配资源*/
{
k++;/*对满足条件的资源计数*/
}
else
printf("\ntheprocessshouldwait.\n");/*否则等待*/
}
if(k==M)/*---------*/
{
for(j=0;j{
av[j]=av[j]-request[j];
al[i][j]=al[i][j]+request[j];
need[i][j]=need[i][j]-request[j];
}
r=s(av,need,al);
if(r==false)/*不安全,回收资源*/
{
for(j=0;j{
av[j]=av[j]+request[j];
al[i][j]=al[i][j]-request[j];
need[i][j]=need[i][j]+request[j];
}
}
else
{
printf("\nIsthereaprocessrequest?
\n");/*安全,继续*/
scanf("%d",&flag);
if(flag)/*判断有无请求*/
f(flag);/*如有,分配*/
else
{
printf("\nshifoujinxingqitajiance?
(y=1,continue.y=0,stop)\n");/*进行另一组检测*/
scanf("%d",&y);
if(y)
c();
}
}
}/*---------*/
else
{
printf("theprocessshouldwait.\n");/*否则等待*/
}
}
}
intc()
{
inti,j,r,flag;/*flag为1,有请求,否则,无请求*/
printf("inputthemumberofsources:
\n");
scanf("%d",&M);
printf("inputthemumberofprocesses:
\n");
scanf("%d",&N);
printf("pleaseinputav:
\n");/*输入现有资源数*/
for(i=0;i{
scanf("%d",&av[i]);
}
printf("pleaseinputeveryprocess'smax:
\n");/*输入每个进程需要资源最大值*/
for(i=0;ifor(j=0;j{
scanf("%d",&max[i][j]);
}
printf("pleaseinputeveryprocess'sal:
\n");/*输入每个进程已分配资源数*/
for(i=0;ifor(j=0;j{
scanf("%d",&al[i][j]);
}
printf("inputeveryprocess'sneed:
\n");/*显示还需资源数*/
for(i=0;i{
for(j=0;j{
need[i][j]=max[i][j]-al[i][j];
printf("%d",need[i][j]);
}
}
r=s(av,need,al);/*安全检测*/
if(r)
{
printf("\nIsthereaprocessrequest?
\n");
scanf("%d",&flag);
if(flag)/*判断有无请求*/
f(flag);/*如有,分配*/
}
}
main()
{
c();/*初始化*/
getch();
}
七.设计小结
一周的操作系统课程设计终于结束了,虽然很忙碌很疲劳,但感觉收获还是蛮大的。
我几乎每天的专注和辛劳,唤回了我对操作系统的重新的认识,在编写程序不断出现错误和改正的过程序中加深了我对银行家算法的理解。
这个系统的功能基本能满足要求,完成了对资源的修改还有用银行家算法和安全性算法来检查是否允许分配资源给进程。
在课程设计的过程中,通过与同组人的相互讨论,很多问题迎刃而解。
让我从中体会到是小组合作的力量。
设计主要由两部分组成。
第一部分:
银行家算法(扫描)
1.如果Request<=Need,则转向2;否则,出错
2.如果Request<=Available,则转向3,否则等待
3.系统试探分配请求的资源给进程
4.系统执行安全性算法
安全性算法
1.设置两个向量
(1).工作向量:
Work=Available(表示系统可提供给进程继续运行所需要的各类资源数目)
(2).Finish:
表示系统是否有足够资源分配给进程(True:
有;False:
没有).初始化为False
2.若Finish[i]=False&&Need<=Work,则执行3;否则执行4(I为资源类别)
3.进程P获得第i类资源,则顺利执行直至完成!
并释放资源:
Work=Work+Allocation;Finish[i]=true;转2
4.若所有进程的Finish[i]=true,则表示系统安全;否则,不安全!
第二部分主要是进行资源的修改。
在这里可以修改资源的可用资源和资源还需求资源。
由于时间有限,还不是很完善,系统还有许多不尽人意的地方。
这些都有待进一步改善
一.程序流程图:
1.初始化算法流程图:
2.银行家算法流程图:
3.安全性算法流程图:
二.银行家算法设计:
1.设进程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)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
2.安全性检查
(1)设置两个工作向量Work=Available;Finish=False
(2)从进程集合中找到一个满足下述条件的进程,
Finish =False
Need<=Work
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work=Work+Allocation
Finish=True
GO TO 2
(4)如所有的进程Finish=true,则表示安全;否则系统不安全。
3.数据结构
假设有M个进程N类资源,则有如下数据结构:
#define W 10
#define R 20
int A ; //总进程数
int B ; //资源种类
int ALL_RESOURCE[W]; //各种资源的数目总和
int MAX[W]; //M个进程对N类资源最大资源需求量
int AVAILABLE; //系统可用资源数
int ALLOCATION[W]; //M个进程已经得到N类资源的资源量
int NEED[W]; //M个进程还需要N类资源的资源量
int Request; //请求资源个数
5.4主要函数说明
void showdata(); //主要用来输出资源分配情况
void changdata(int); //主要用来输出资源分配后后的情况
void rstordata(int); //用来恢复资源分配情况,如:
银行家算法时,由于分配不安全则要恢复资源分配情况
int chkerr(int); //银行家分配算法的安全检查
void bank() ; //银行家算法
银行家算法的课程设计
(二)VC++6.02008-01-28 15:
29源程序
数据结构分析:
假设有M个进程N类资源,则有如下数据结构:
#define W 10
#define R 20
int A ; //总进程数
int B ; //资源种类
int ALL_RESOURCE[W]; //各种资源的数目总和
int MAX[W]; //M个进程对N类资源最大资源需求量
int AVAILABLE; //系统可用资源数
int ALLOCATION[W]; //M个进程已经得到N类资源的资源量
int NEED[W]; //M个进程还需要N类资源的资源量
int Request; //请求资源个数
第3章 程序清单#include
using namespace std;
#define MAXPROCESS 50 /*最大进程数*/
#define MAXRESOURCE 100 /*最大资源数*/
int AVAILABLE[MAXRESOURCE]; /*可用资源数组*/
int MAX[MAXPROCESS][MAXRESOURCE]; /*最大需求矩阵*/
int ALLOCATION[MAXPROCESS][MAXRESOURCE]; /*分配矩阵*/
int NEED[MAXPROCESS][MAXRESOURCE]; /*需求矩阵*/
int REQUEST[MAXPROCESS][MAXRESOURCE]; /*进程需要资源数*/
bool FINISH[MAXPROCESS]; /*系统是否有足够的资源分配*/
int p[MAXPROCESS]; /*记录序列*/
int m,n; /*m个进程,n个资源*/
void Init();
bool Safe();
void Bank();
int main()
{
Init();
Safe();
Bank();
}
void Init() /*初始化算法*/
{
int i,j;
cout<<"\t---------------------------------------------------"< cout<<"\t|| ||"< cout<<"\t|| 银行家算法 ||"< cout<<"\t|| ||"< cout<<"\t|| 计科04151 李宏 ||"< cout<<"\t|| ||"< cout<<"\t|| 0415084211 ||"< cout<<"\t---------------------------------------------------"< cout<<"请输入进程的数目:
";