银行家算法用C语言实现课程设计报告.docx
《银行家算法用C语言实现课程设计报告.docx》由会员分享,可在线阅读,更多相关《银行家算法用C语言实现课程设计报告.docx(22页珍藏版)》请在冰豆网上搜索。
银行家算法用C语言实现课程设计报告
成绩
课程设计报告
题目银行家算法程序设计
课程名称操作系统课程设计
院部名称信息技术学院
专业计算机科学与技术
班级
学生姓名**
学号**********
课程设计地点
课程设计学时20
指导教师**
*******教务处制
操作系统课程设计报告
摘要
Dijkstra提出的银行家算法,是最具代表性的避免死锁的算法。
本文对如何用银行家算法来处理操作系统给进程分配资源做了详细的说明,包括需求分析、概要设计、详细设计、测试与分析、总结、源程序清单。
首先做了需求分析,解释了什么是银行家算法,并指出它在资源分配中的重要作用。
然后给出了银行家算法的概要设计,包括算法思路、步骤,以及要用到的主要数据结构、函数模块及其之间的调用关系等。
在概要设计的基础上,又给出了详细的算法设计,实现概要设计中定义的所有函数,对每个函数写出核心算法,并画出了流程图。
接着对编码进行了测试与分析(并在最后附上Java编写的程序代码)。
最后对整个设计过程进行了总结。
关键词:
安全状态;安全序列;银行家算法;安全性算法;安全序列;流程图。
摘要…………………………………………………………………………………1
目录…………………………………………………………………………………2
1.绪论…………………………………………………………………………………3
1.1前言……………………………………………………………………………3
1.2研究意义………………………………………………………………………4
1.3结构安排………………………………………………………………………4
2.需求分析……………………………………………………………………………5
2.1题目描述………………………………………………………………………5
2.2银行家算法……………………………………………………………………5
2.3基本要求………………………………………………………………………5
2.4目的……………………………………………………………………………6
3.概要设计……………………………………………………………………………7
3.1设备环境………………………………………………………………………7
3.2算法思路………………………………………………………………………7
3.3银行家算法步骤………………………………………………………………7
3.4安全性算法步骤………………………………………………………………8
3.5数据结构………………………………………………………………………9
3.6系统结构图……………………………………………………………………12
4.详细设计 ………………………………………………………………………13
4.1主要函数的核心代码………………………………………………………13
4.2程序流程图…………………………………………………………………13
5.测试………………………………………………………………………………16
5.1测试用例……………………………………………………………………16
5.2测试结果截图………………………………………………………………17
6.总结………………………………………………………………………………22
参考文献……………………………………………………………………………24
致谢…………………………………………………………………………………25
附录…………………………………………………………………………………26
1绪论
1.1前言:
Dijkstra(1965)提出了一种能够避免死锁的调度算法,称为银行家算法。
它的模型基于一个小城镇的银行家,他向一群客户分别承诺了一定的贷款额度,每个客户都有一个贷款额度,银行家知道不可能所有客户同时都需要最大贷款额,所以他只保留一定单位的资金来为客户服务,而不是满足所有客户贷款需求的最大单位。
这里将客户比作进程,贷款比作设备,银行家比作系统。
客户们各自做自己的生意,在某些时刻需要贷款。
在某一时刻,客户已获得的贷款和可用的最大数额贷款称为与资源分配相关的系统状态。
一个状态被称为是安全的,其条件是存在一个状态序列能够使所有的客户均得到其所需的贷款。
如果忽然所有的客户都申请,希望得到最大贷款额,而银行家无法满足其中任何一个的要求,则发生死锁。
不安全状态并不一定导致死锁,因为客户未必需要其最大贷款额度,但银行家不敢抱这种侥幸心理。
银行家算法就是对每一个请求进行检查,检查如果满足它是否会导致不安全状态。
若是,则不满足该请求;否则便满足。
检查状态是否安全的方法是看他是否有足够的资源满足一个距最大需求最近的客户。
如果可以,则这笔投资认为是能够收回的,然后接着检查下一个距最大需求最近的客户,如此反复下去。
如果所有投资最终都被收回,则该状态是安全的,最初的请求可以批准。
1.2研究意义:
在多道程序系统中,多个进程的并发执行来改善系统的资源利用率,提高系统的吞吐量,但可能发生一种危险——死锁。
所谓死锁(Deadlock),是指多个进程在运行过程中因争夺资源而造成的一种僵局(DeadlyEmbrace),当进程处于这种状态时,若无外力作用,他们都无法在向前推进。
要预防死锁,有摒弃“请求和保持”条件,摒弃“不剥夺”条件,摒弃“环路等待”条件等方法。
但是,在预防死锁的几种方法之中,都施加了较强的限制条件;而在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。
在该方法中把系统状态分为安全状态和不安全状态,便可避免死锁的发生。
而最具代表性的避免死锁的算法,便是Dijkstra的银行家算法。
利用银行家算法,我们可以来检测CPU为进程分配资源的情况,决定CPU是否响应某进程的的请求并为其分配资源,从而很好避免了死锁的产生。
1.3结构安排:
一、绪论:
介绍了题目背景以及研究意义。
二、需求分析:
介绍了题目描述、银行家算法、以及基本要求和所需达到的目的。
三、概要设计:
介绍了基本的算法思路、步骤,以及数据结构和主要的函数模块及其调用关系。
四、详细设计:
介绍了主要函数及其核心代码,以及程序流程图。
五、测试
六、总结
参考文献
附录:
原程序清单
2需求分析
2.1题目描述:
银行家算法是一种最具有代表性的避免死锁的算法。
所谓安全状态,是指系统能按照某种进程顺序{P1,P2,…,Pn}(称{P1,P2,…,Pn}序列为安全序列),来为每个进程Pi分配其所需资源,直至满足每个进程对资源的最大需求,使每个进程都可以顺利完成。
安全状态一定没有死锁发生。
如果系统无法找到这样一个安全序列,则称系统处于不安全状态。
那么,什么是安全序列呢?
如果对每一个进程Pi(1
2.2银行家算法:
我们可以把操作系统看做是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求资源相当于客户向银行家贷款。
操作系统按银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程尚需求的资源量,若是系统现存的资源可以满足它尚需求的资源量,则按当前的申请量来分配资源,否则就推迟分配。
当进程在执行中继续申请资源时,先测试该进程申请的资源量是否超过了它尚需的资源量。
若超过则拒绝分配,若没超过则再测试系统尚存的资源是否满足该进程尚需的资源量,若满足即可按当前的申请量来分配,若不满足亦推迟分配。
2.3基本要求:
设计一n个并发进程共享m个系统资源的程序实现银行家算法。
要求包括:
(1)简单的初始化界面;
(2)系统资源的占用和剩余情况;
(3)为进程分配资源,用银行家算法对其进行检测,分为以下三种情况:
A.所申请的资源大于其所需资源,提示分配不合理不予分配并返回;
B.所申请的资源未大于其所需资源,但大于系统此时的可利用资源,提示分配不合理不予分配并返回;
C.所申请的资源未大于其所需资源,亦未大于系统此时的可利用资源,预分配并进行安全性检查:
a.预分配后系统是安全的,将该进程所申请的资源予以实际分配并打印后返回;
b.与分配后系统进入不安全状态,提示系统不安全并返回;
(4)对输入进行检查,即若输入不符合条件,应当报错并返回重新输入;
(5)撤销作业,释放资源。
2.4目的:
银行家算法是避免死锁的一种重要方法,本设计要求用C语言编写和调试一个简单的银行家算法程序。
加深有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。
通过设计这个算法,让学生能够对书本知识有更深的理解,在操作和其它方面有更高的提升,对程序设计的水平也有所提高。
根据设计题目的要求,充分地分析和理解题目,叙述系统的要求,明确程序要求实现的功能以及限制条件。
明白自己需要用代码实现的功能,清楚编写每部分代码的目的,做到有的放矢,有条理不遗漏的用代码实现银行家算法。
3概要设计
3.1设备环境:
软件:
windowsXP,MicrosoftOfficcWord2003,MicrosoftOfficcVisio2003,TurboC2.0
硬件:
CPU:
2.00GHZ内存:
0.99GB主频:
2.00HZ
3.2算法思路:
先对用户提出的请求进行合法性检查,即检查请求是否大于需要的,是否大于可利用的。
若请求合法,则进行预分配,对分配后的状态调用安全性算法进行检查。
若安全,则分配;若不安全,则拒绝申请,恢复到原来的状态,拒绝申请。
3.3银行家算法步骤
(1)如果Requesti<or=Need,则转向步骤
(2);否则,认为出错,因为它所需要的资源数已超过它所宣布的最大值。
(2)如果Request<or=Available,则转向步骤(3);否则,表示系统中尚无足够的资源,进程必须等待。
(3)系统试探把要求的资源分配给进程Pi,并修改下面数据结构中的数值:
Available=Available-Request[i];
Allocation=Allocation+Request;
Need=Need-Request;
(4)系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。
3.4安全性算法步骤
(1)设置两个向量
①工作向量Work。
它表示系统可提供进程继续运行所需要的各类资源数目,执行安全算法开始时,Work=Allocation;
②标志向量Finish。
它表示系统是否有足够的资源分配给进程,使之运行完成,开始时先做Finish[i]=0,当有足够资源分配给进程时,令Finish[i]=1。
(2)从进程集合中找到一个能满足下述条件的进程:
①Finish[i]=0
②Need如找到,执行步骤(3);否则,执行步骤(4)。
(3)当进程P获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
Work=Work+Allocation;
Finish[i]=1;
转向步骤
(2)。
(4)如果所有进程的Finish[i]=1,则表示系统处于安全状态;否则,系统处于不安全状态。
3.5数据结构:
3.5.1主要用到的数据结构:
(1)工作向量(已分配矩阵)rdy[]
(2)仍需求矩阵nd[][]=max[][]-rdy[]
(3)可利用资源向量sys[]
(4)申请各类资源向量req[]
(5)等待向量wait[]
(6)标志向量zhuang[]
3.5.2程序模块:
main()//系统的主函数
intpstart()//初始化
voidinputpcb()//输入资源及进程
voidcsh()//数据备份
voidoutputpcb()//打印输出
voidinputreq()//提出资源请求
intcanloc()//判断请求
intchange(inta[10],intb)//假设满足请求后,修改资源个数
intexchange(inta[10],intb)//请求不能满足,恢复资源个数
intss(intri)//判断是否有安全序列
intlocate()//利用安全性算法进行安全性检测
voidagree()//资源分配后修改资源个数
voidoutput()//输出安全序列
voidback()//撤销作业,归还资源
3.5.3各模块间的调用关系:
主函数main()
要调用:
pstart();inputpcb();csh();outputpcb();inputreq();canloc();
ss(ri);change(req,qq);output();agree();exchange(req,qq);
初始化函数pstart()
要调用:
exit;back();
银行家算法函数ss()
要调用:
locate();
3.6系统结构图
4详细设计
4.1主要函数的核心代码:
1.进行初始化输入的函数
2.打印输出的函数
3.利用安全性算法进行检测的函数
4.进行资源分配的函数
5.利用行家算法进行判定的函数
4.2程序流程图:
1、系统主要过程流程图
2、银行家算法流程图
3、安全性算法流程图
5测试
5.1测试用例:
测试用例为课本上的例题:
某系统有R1、R2和R3共3种资源,在T0时刻P1、P2、P3、P4和P5这5个进程对资源的占用和需求情况见下表,此刻系统的可用资源为(3,3,2)。
进程AllocationNeedAvailiable
R1R2R3R1R2R3R1R2R3
1010743322
2200122
3302600
4211011
5002431
取了4种不同的例子,来测试系统的主要功能是否实现:
进程iRequest[i]检测结果
a.1722Request>Available
b.4211Request>Need
c.1101可以分配
d.2121系统不安全
5.2测试结果截图:
1.开始界面
2.初始化并打印输出
3.用例测试a:
进程1发出请求Request(7,2,2)——Request>Available,不予分配,保存请求,当资源足够时再行分配。
4.用例测试b:
进程4发出请求Request(2,1,1)——Request>Need,不予分配。
5.用例测试c:
进程1发出请求Request(1,0,1)——可以分配。
6.用例测试d:
进程2发出请求Request(1,2,1)——系统不安全。
7.输入测试a:
如果进行作业2的撤消,且进行资源的回收。
8.输入测试b:
如果进行作业1的撤消,且进行资源的回收;若等待队列中也有相应的作业,则一起删除。
9.输入测试c:
所作业全部撤销后,显示系统可用资源。
10.输入测试a:
输入a,则退出运行。
6总结
在银行家算法这个系统之中,所采用的数据结构应是最基本的部分。
银行家算法的数据结构我们采用了一维数组与二维数组来存储,比如已分配资源数rdy[]、仍需求资源数nd[]、以及系统可利用的资源数sys[]、申请各类资源req[]、进程个数jc[]等数组,其中每一个进程还使用了结构体。
数据结构虽然重要但却只是基础,而最主要的用以实现系统功能的应该有两个部分,一是用银行家算法来判断,二是用安全性算法来检测系统的安全性。
在本程序代码中,银行家算法用canloc()函数来实现。
首先,输入欲申请资源的进程以及其所申请的资源数,存放在qq变量和req数组中。
然后,判断进程请求的资源数是否大于其所需的资源数,若大于则报错并返回,若不大于则继续判断它是否大于系统在此时刻可利用的资源数,同样,如果大于则报错并反回,如果不大于则调用change()函数来进行预分配,之后再调用安全型算法ss检查,若检查结果为不安全,则调用exchange()函数来改回原值。
最后,无论此次分配是否成功,我们都可以选择继续分配或者退出系统或者撤销进程。
安全性检测我们是用locate()函数来实现的。
首先,zhuang[]为布尔型,默认是0,即该进程未完成。
而sys——即该系统中可以用来工作的资源数——最开始为系统最初可以用的资源数。
然后,我们从第一个进程开始判断该进程未完成且其所需求的资源量不大于该系统中可以用来工作的资源量这个条件是否成立,即zhuang[]=0且jc[].nd[]<=sys[]是否成立。
成立的话则将当前在工作的资源量与该进程已分配的资源量相加,存放于当前可用来工作的资源量当中,即Work[]=Work[]+Allocation,并将zhuang[]=1。
否则便将此进程的优先级减一,排在队位,然后开始往后循环。
待所有的进程循环完毕,我们再次判断是否还存在进程的zhuang[]=0,如果仍存在,则说明系统没有安全序列,处于不安全状态,不可以进行分配;否则,系统处于安全状态,将预分配变为实际分配,求出安全序列并且将实际分配后的资源分配情况打印输出。
除此之外,在程序当中,我们也得强调一下对输入的合法性的判断。
比如,我们输入的欲申请资源的进程号没有在系统已存在的进程当中,或者进程号定义为整型,但是却错输成字母等情况,我们需要对这些情况进行判断,让程序报错返回而并非因错误而中断。
这样的情况处理起来比较麻烦,相当于对每次输入针对各种不同的情况都得做判断。
我也没有涵盖全部的输入,仅仅只是对输入的进程号不在已存在进程当中、以及输入的操作选择不存在两种情况分别作了判断,并且针对第二种情况设定了五次输入错误的话系统关闭的功能。
而因为对于某些——比如进程号——本来设定就是整型,因此对输入的是字母的判别因比较复杂而未能加上。
总之,银行家算法是避免死锁的主要方法,其思路在很多方面都非常值得我们来学习借鉴。
参考文献
[1]汤小丹,梁红兵,哲凤屏,汤子瀛.计算机操作系统.西安:
西安电子科技大学出版社,2007.
[2]严蔚敏,吴伟民.数据结构.北京:
清华大学出版社,2006.
[3]田祥宏,沈奇,王旭辉,吕艳琳.C语言程序设计.西安:
西安电子科技大学出版社,2007.
[4](XX文库:
银行家算法报告)
[5](志文工作室:
银行家算法模拟实现)
致谢
历时将近两个星期的时间终于将这篇课程设计报告写完,在报告的写作过程中遇到了无数的困难和障碍,都在同学和老师的帮助下度过了。
尤其要强烈感谢我的课设指导老师何健老师,他对我进行了无私的指导和帮助,不厌其烦的帮助进行论文的修改和改进。
另外,在校图书馆查找资料的时候,图书馆的老师也给我提供了很多方面的支持与帮助。
在此向帮助和指导过我的各位老师表示最中心的感谢!
感谢这篇论文所涉及到的各位学者。
本文引用了数位学者的研究文献,如果没有各位学者的研究成果的帮助和启发,我将很难完成本篇论文的写作。
感谢我的同学和朋友,在我写论文的过程中给予我了很多你问素材,还在论文的撰写和排版灯过程中提供热情的帮助。
由于我的学术水平有限,所写论文难免有不足之处,恳请各位老师和学友批评和指正!
附录:
源程序主模块清单
#include //头文件
structpcb //结构体定义
{intrdy[10];
intnd[10];
}jc[10],tjc[10];
intsys[10],tsys[10];
intnn,n,g,qq,ri=0,a=0,ww[10],wait[10][10],req[10],as[10],tzhuang[10];
chartcs;//定义全局变量
voidinputreq()//某一进程得出资源请求
{inti,j=0;
printf("pleaseinputthePCBrequested\n\nIfyouhavenorequest,youcancheckthewait!
\n\n");
scanf("%d",&qq);
oo:
if(qq>1000||qq<0)
{printf("pleaseinputthePCBrequested\n\n");scanf("%d",&qq);}
for(i=1;i<=n;i++)
if(qq==i)j++;
if(j<1){printf("meiyouxiangtongdejincheng,pleaseinputthePCBrequested\n\n");scanf("%d",&qq);gotooo;}
printf("pleaseinputthesourcerequested\n\n");
for(i=1;i<=nn;i++)
{scanf("%d",&req[i]);
ooo:
if(req[i]>1000||req[i]<0){printf("pleaseinputthesourcerequested\n\n");scanf("%d",&req[i]);gotoooo;}
}
}
intlocate() //查找安全序列
{inti,j,k;
for(g=1;g<=n;g++)
{j=0;
if(zhuang[g]==0)
{for(i=1;i<=nn;i++)
if(jc[g].nd[i]>sys[i])
{j=1;i=nn;}
if(j==0)
{for(k=1;k<=nn;k++)
{sys[k]+=jc[g].rdy[k];
zhuang[g]=1;
}
return(g);
}
}
}
return0;
}
intcanloc() //判断请求是否合理
{inti,j=0;
for(i=1;i<=nn;i++)
if(req[i]>(jc[qq].nd[i]))j=1;
if(j==1)return2;
for(i=1;i<=nn;i++)
if(req[i]>sys[i])j=1;
if(j==0)return1;
elsereturn0;
}
voidback()//撤销进程,回收资源
{inti,j,k,d;