模拟实现银行家算法 3.docx

上传人:b****5 文档编号:28057126 上传时间:2023-07-07 格式:DOCX 页数:31 大小:74.75KB
下载 相关 举报
模拟实现银行家算法 3.docx_第1页
第1页 / 共31页
模拟实现银行家算法 3.docx_第2页
第2页 / 共31页
模拟实现银行家算法 3.docx_第3页
第3页 / 共31页
模拟实现银行家算法 3.docx_第4页
第4页 / 共31页
模拟实现银行家算法 3.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

模拟实现银行家算法 3.docx

《模拟实现银行家算法 3.docx》由会员分享,可在线阅读,更多相关《模拟实现银行家算法 3.docx(31页珍藏版)》请在冰豆网上搜索。

模拟实现银行家算法 3.docx

模拟实现银行家算法3

 

模拟实现银行家算法

 

学院

专业

学号

学生姓名

指导教师姓名

 

2014年3月18日

目录

1课设简介1

1.1课程设计题目1

1.2课程设计目的1

1.3课程设计内容1

1.4时间安排2

2实验原理分析2

2.1问题描述2

2.2问题分析3

2.3解决方法3

3主要的功能模块3

3.1程序流程图:

3

3.2数据结构4

3.3算法整体设计与调用5

3.4模块设计与时间复杂度分析5

3.5运行结果6

3.6测试用例7

4总结及参考文献8

4.1总结8

4.2参考文献8

5源代码8

1课设简介

1.1课程设计题目

模拟实现银行家算法

1.2课程设计目的

操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决实际问题的机会。

1)进一步巩固和复习操作系统的基础知识。

2)培养学生结构化程序、模块化程序设计的方法和能力。

3)提高学生调试程序的技巧和软件设计的能力。

4)提高学生分析问题、解决问题以及综合利用C语言进行程序设计的能力。

1.3课程设计内容

运用银行家算法,避免死锁的发生。

在确保当前系统安全的前提下推进的。

对进程请求先进行安全性检查,来决定资源分配与否,从而确保系统的安全,有效的避免了死锁的发生。

问题的关键在于安全性算法,即找安全性序列。

1.4时间安排

1)分析设计贮备阶段(1天)

2)编程调试阶段(7天)

3)写课程设计报告、考核(2天)

2实验原理分析

2.1问题描述

我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。

为保证资金的安全,银行家规定:

(1)当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客;

(2)顾客可以分歧贷款,但贷款的总数不能超过最大需求量;

(3)当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款;

(4)当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金.

操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。

当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。

若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。

死锁

死锁是进程死锁的简称,是由Dijkstra于1965年研究银行家算法时首先提出来的。

是指多个进程循环等待它方占有的资源而无限期地僵持下去的局面。

很显然,如果没有外力的作用,那麽死锁涉及到的各个进程都将永远处于封锁状态。

它是计算机操作系统乃至并发程序设计中最难处理的问题之一。

实际上,死锁问题不仅在计算机系统中存在,在我们日常生活中它也广泛存在。

在计算机系统中,涉及软件,硬件资源都可能发生死锁。

例如:

系统中只有一台CD-ROM驱动器和一台打印机,某一个进程占有了CD-ROM驱动器,又申请打印机;另一进程占有了打印机,还申请CD-ROM。

结果,两个进程都被阻塞,永远也不能自行解除。

安全性序列

安全序列的的实际意义在于:

系统每次进行资源分配后,如果对于系统中新的资源状况,存在一个安全序列,则至少存在一条确保系统不会进入死锁的路径。

按照该序列,银行家可以实施一个有效的分配过程使得所有客户得到满足

银行家算法的核心在于安全序列的产生。

安全序列正是一种安全的进程推进顺序

2.2问题分析

(1)从键盘输入当前系统的资源信息,包括当前可用资源,每个进程对各类资源的最大需求量,每个进程当前已分配的各个资源量和每个进程尚需要的各个资源量,输出结果显示在DOS界面上;

(2)输入进程请求,按照设计好的安全性算法进行检查,得到结果并输出整个执行过程的相关信息和最终结果(主要包括资源分配表和安全序列)

(3)要求要有各种异常的处理,程序的可控制性和可连续性执行。

包括对进程的存在有无检查,请求向量的不合法检查,试分配失败后的数据恢复和重新接受进程请求等。

2.3解决方法

该算法选用结构化的设计方法,将该系统划为四块,分别是:

(1)主模块,处在整个系统的最高层,负责组织调用其他模块。

(2)初始化模块,负责从键盘读入系统资源和进程状态,并将系统初识资源分配状态打印。

(3)试分配模块,负责处理进程请求,和相应的数据结构的修改,已经特殊情况的处理。

(4)安全性检查,负责试分配后的安全性检查,以及系统不安全时的资源

3主要的功能模块

3.1程序流程图:

3.2数据结构

主要的数据结构及模块有:

typedefstructmy_process

{

intnum;//进程标号

intMax[M];//表示某个进程对某类资源的最大需求

intAllocation[M];//表示某个进程已分配到某类资源的个数

intNeed[M];//表示某个进程尚需要某类资源的个数

structmy_process*next;//指向下一个结点(进程)

}process;

intAvailable[M]={0};//其中每一个数组元素表示当前某类资源的可用数目,初始化为系统所提供的资源的最大数目

intRequest[M]={0};//请求向量

intRecord_work[N][M]={0};//存储当前work[]的值,以便输出

intSafety[N]={0};//存储安全序列,以便后面排序

3.3算法整体设计与调用

主函数voidmain()主要分四大块:

(1)首先需要初始化Init_process(process**head,intm,int*count),存储系统当前状态信息;

(2)调用安全算法Safety_Algorithm,检测当前系统安全状态,若安全则进行下一步,否则打印相关信息,程序退出。

(3)调用试分配函数Attempt_Allocation,进行试分配,若试分配成功,修改相关数据结构,打印当前系统资源分布图,转下一步,否则,打印提示信息,接收其他请求向量。

(4)再次调用安全性算法,检查试分配以后的系统安全性,若安全打印安全性序列和当前系统资源分布图,并进入新一轮的执行。

否则之前的试分配作废,恢复试分配之前的数据结构,输出相关提示信息,接收下一个进程请求

3.4模块设计与时间复杂度分析

3.4.1系统资源初始化函数Init_process

(1)首先读入系统可用资源。

(2)用malloc()函数动态创建进程并且输入相关资源Max[M],Allocation[M],Need[M]。

进程之间以链表组织,输入-1结束初始化。

for(i=0;i

{

scanf("%d",&node.Need[i]);//初始化资源

}

Insret_Tail(head,node);//插入链尾

(*count)++;//资源个数加1

3.4.2安全性算法Safety_Algorithm

找安全序列,其中用到查找当前合法进程的函数process*Reasonable()

(1)先初始化相关数据结构

work=(int*)malloc(m*sizeof(int));//当前系统可用资源

finish=(int*)malloc(n*sizeof(int));//标记向量,初始为false,通过安全检查后最为true

(2)Reasonable(head,finish,work,m,n)函数,找到当前可执行的进程,执行Alter_Data()修改当前数据结构。

(3)while(count

(2)

3.4.3接受进程请求,试分配Attempt_Allocation(head,Request,Available,M);

(1)先判断标志flag的值,若为真,则执行Attempt_Allocation函数,该flag是由Safety_Algorithm返回的。

(2)进入Safety_Algorithm函数,首先输入进程号,并检查该进程是否存在,存在则输入它的请求向量,并进行检查。

request[i]<=p->Need[i]

request[i]<=avail[i]

若以上两个条件都为真,试分配成功,则执行Alter_Data()函数,修改相关数据结构,否则该进程被阻塞,系统转而接受其他请求

avail[i]=avail[i]-request[i];

p->Allocation[i]=p->Allocation[i]+request[i];

p->Need[i]=p->Need[i]-request[i];

将结果打印出来。

3.4.4对试分配后的系统,进行安全性检查Safety_Algorithm。

执行过程同4.4.2大致一样,唯一一点在于当找不到安全序列时,将本次试分配作废,恢复该次试分配之前的数据结构。

3.5运行结果

初始化系统资源模块Init_process(process**head,intm,int*count)的测试

初始化过程,并打印结果。

试分配模块Attempt_Allocation的测试:

试分配模块,主要是在系统进过第一次安全检查后,对系统资源的一次尝试性分配,试分配完成后,相关的数据结构被修改。

安全模块Safety_Algorithm的调试

(1)试分配前的安全算法,结果如果输出一个安全性序列,并且经过人工检查该安全性序列,确实有效,则该模块正确;如果系统不安全,打印出相关信息,返回上一层。

效果如下图示:

(2)试分配后的安全算法,结果如果输出一个安全性序列,并且经过人工检查该安全性序列,确实有效,则该模块正确;否则,之前的试分配作废,恢复试分配前的资源状态。

3.6测试用例

T0时刻的资源分配表(各种资源的数量分别为:

10、5、7)

资源情况

进程

Max

ABC

Allocation

ABC

Need

ABC

Available

ABC

P0

753

010

743

332

P1

322

200

122

P2

902

302

600

P3

222

211

011

P4

433

002

431

各模块测试通过后,集成在一起测试,系统初始资源和模块测试时保持一致,以下是一组测设用例以及结果,基本包括了该算法的所有情况。

鉴于整个过程的截图较大,所以省略,部分过程可参看上面模块测试截图。

(1)p6:

结果;无此进程

(2)P1:

Request(2,0,2)结果;系统不能满足

(3)P1:

Request(1,0,2)结果;两次安全性检查都通过,并打印出最终结果

(4)P0:

Request(0,2,0)结果;试分配后,系统不安全,试分配作废

(5)P0:

Request(0,1,0)结果;两次安全性检查都通过,并打印出最终结果

 

4总结及参考文献

4.1总结

1)银行家算法很好的解决了系统资源分配过程中的进程死锁问题.

2)通过具体的调试运行很多问题得到解决,进一步增强了我们的解决实际问题的动手能力.

4.2参考文献

[1]严蔚敏吴伟民,.数据结构(C语言版),1999,清华大学出版社;

[2]汤小丹梁红兵哲凤屏汤子嬴,计算机操作系统(第三版)西安电子科技大学出版社;

 

5源代码

//银行家算法

#include

#include

#include

#defineM100//系统资源的种类

#defineN100//进程上限

typedefstructmy_process

{

intnum;//进程标号

intMax[M];//表示某个进程对某类资源的最大需求

intAllocation[M];//表示某个进程已分配到某类资源的个数

intNeed[M];//表示某个进程尚需要某类资源的个数

structmy_process*next;

}process;

voidInsret_Tail(process**head,processnode)//尾插法建立进程链表

{

process*p=(process*)malloc(sizeof(process));

process*last=NULL;

memcpy(p,&node,sizeof(process));//动态创建进程结点

p->next=NULL;

if(NULL==*head)

{

*head=p;

}

else//找表尾

{

last=*head;

while(last->next!

=NULL)

{

last=last->next;

}

last->next=p;//插入链尾

}

}

voidInit_process(process**head,intm,int*count)//初始化系统资源

{

inti,j=0;

processnode;

printf("请初始化一组进程,进程编号从0开始,输入-1结束输入:

\n");

do

{

node.num=j++;

printf("请输入第%d个进程信息:

\n",node.num);

printf("最大需求矩阵:

");

scanf("%d",&node.Max[0]);

if(node.Max[0]!

=-1)//输入-1结束输入

{

for(i=1;i

{

scanf("%d",&node.Max[i]);

}

printf("分配矩阵:

");

for(i=0;i

{

scanf("%d",&node.Allocation[i]);

}

printf("需求矩阵:

");

for(i=0;i

{

//scanf("%d",&node.Need[i]);

node.Need[i]=node.Max[i]-node.Allocation[i];

printf("%d",node.Need[i]);

if(node.Need[i]<0)

{

printf("输入的需求矩阵有误或者需求大于最大矩阵,处于不安全状态!

!

!

!

!

\n");

exit(0);

}

}

printf("\n");

Insret_Tail(head,node);//插入链尾

(*count)++;//进程数加1

}

else

{

break;

}

}

while

(1);

}

voidPrint(process*head,int*avail,intm)//打印初识系统资源

{

process*p=NULL;

intcount=0;

inti,j;

charch;

p=head;

if(NULL==p)

{

printf("当前无进程!

\n");

exit(0);

}

else

{

printf("\n|num||Max||Allocation||Need||Available|\n");

 

printf("\t");

for(i=0;i<4;i++)

{

ch='A';

for(j=0;j

{

printf("%4c",ch++);

}

printf("\t");

}

printf("\n");

while(p!

=NULL)

{

count++;

printf("%8.2d",p->num);

for(j=0;j

{

printf("%4d",p->Max[j]);

}

printf("\t");

for(j=0;j

{

printf("%4d",p->Allocation[j]);

}

printf("\t");

for(j=0;j

{

printf("%4d",p->Need[j]);

}

printf("\t");

if(count==1)

{

for(j=0;j

{

printf("%4d",avail[j]);

}

}

printf("\n");

p=p->next;

}

printf("\n");

}

}

process*Location(process*head,intpro_num)//进程定位函数,找到当前请求进程在进程链表中的位置,以便后面对其操作

{

process*p=NULL;

p=head;

if(NULL==p)

{

printf("error!

\n");//异常,当前链表为空

returnp;

}

else

{

while(p!

=NULL)

{

if(p->num==pro_num)

{

break;

}

else

{

p=p->next;

}

}

if(NULL==p)//无此进程,输入错误

{

printf("无此进程!

\n");

returnp;

}

else

{

returnp;

}

}

}

process*Attempt_Allocation(process*head,int*request,int*avail,intm)

{//试分配

intnum,i;

process*p=NULL;

printf("请输入进程编号:

\n");

scanf("%d",&num);

p=Location(head,num);

if(NULL==p)

{

printf("无此进程!

\n");

returnp;

}

printf("请输入该进程的请求向量:

\n");

for(i=0;i

{

scanf("%d",&request[i]);

}

for(i=0;i

{

if(request[i]<=p->Need[i])

{

continue;

}

else

{

printf("该请求系统不能满足!

\n");

returnNULL;

}

}

for(i=0;i

{

if(request[i]<=avail[i])

{

continue;

}

else

{

printf("该请求系统不能满足!

\n");

returnNULL;

}

}

for(i=0;i

{

avail[i]=avail[i]-request[i];

p->Allocation[i]=p->Allocation[i]+request[i];

p->Need[i]=p->Need[i]-request[i];

}

returnp;

}

process*Reasonable(process*head,int*finish,int*work,intm,intn)//找当前可执行的进程

{

inti=0,j=0,count=0;

process*p=NULL;

while

(1)

{

if(finish[i]!

=-1)//表示该进程未执行安全性检查

{

p=Location(head,finish[i]);//定位该进程

if(p!

=NULL)

{

for(j=0;j

{

if(p->Need[j]>work[j])

{

break;

}

else

{

continue;

}

}

if(j==m)

{

returnp;

}

else

{

i++;//当前进程检查没有通过,则进行下一个进程的检查

}

}

}

else

{

i++;//当前进程已经检查过,则进行下一个进程的检查

}

if(i==n)

{

returnNULL;//遍历所有进程都未找到,则跳出返回NULL

}

}

}

voidAlter_Data(process*p,int*work,int*finish,intrecord[][M],intm)//修改相关数据结构

{

inti;

for(i=0;i

{

record[p->num][i]=work[i];

work[i]=work[i]+p->Allocation[i];

}

finish[p->num]=-1;//表示该进程已通过安全性检查

}

intSafety_Algorithm(process*head,int*avail,int*safety,intRecord[][M],intm,intn)//安全性算法

{

int*work=NULL;

int*finish=NULL;

process*p=NULL;

process

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1