中南大学操作系统课程设计.docx
- 文档编号:30391905
- 上传时间:2023-08-14
- 格式:DOCX
- 页数:21
- 大小:267.72KB
中南大学操作系统课程设计.docx
《中南大学操作系统课程设计.docx》由会员分享,可在线阅读,更多相关《中南大学操作系统课程设计.docx(21页珍藏版)》请在冰豆网上搜索。
中南大学操作系统课程设计
操作系统课程设计
题目名称:
银行家算法
姓名
学号
专业
班级
指导教师
编写日期
目录
第一章问题描述3
1.1课设题目重述3
1.2问题分析3
1.3实验环境3
第二章系统设计4
3.1主要数据结构4
3.2银行家算法4
3.3安全性检查算法6
3.4银行家算法安全性序列分析之例7
第三章源代码清单10
3.1函数清单10
3.2各函数的调用关系图12
第四章运行结果测试与分析13
4.1程序的正常输出结果13
4.2程序的差错控制15
第五章结论与心得18
[参考文献]18
第一章问题描述
1.1课设题目重述
设计目的:
了解多道程序系统中,多个进程并发执行的资源分配。
设计要求:
管理员可以把一定数量的作业供多个用户周转使用,为保证作业的安全,管理员规定:
当一个用户对作业的最大需求量不超过管理员现有的资金就要接纳该用户;用户可以分期贷款,但贷款的总数不能超过最大需求量;当管理员现有的作业不能满足用户的所需数时,对用户的请求可以推迟支付,但总能使用户在有限的时间里得到请求。
当用户得到所需的全部作业后,一定能在有限的时间里归还所有的作业。
1.2问题分析
银行家算法是最具有代表性的避免死锁的算法。
我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
在死锁的避免中,银行家算法把系统状态分为安全状态和不安全状态,只要能使系统始终处于安全状态,便可以避免发生死锁。
所谓安全状态,是指系统能按某种顺序为每个进程分配所需资源,直到最大需求,使每一个进程都可以顺利完成,即可找到一个安全资源分配序列。
所以我们需要解决问题有:
1)熟悉银行家算法的工作原理,明白如何判断系统处于安全状态,避免死锁。
2)在Windows操作系统上,如何利用Win32API编写多线程应用程序实现银行家算法。
3)创建n个线程来申请或释放资源,如何保证系统安全,批准资源申请。
4)通过Win32API提供的信号量机制,实现共享数据的并发访问。
1.3实验环境
操作系统:
windows8.1
实验语言:
c++
第二章系统设计
3.1主要数据结构
1)可利用资源向量Available。
如果Available[j]=K,则表示系统中现有Rj类资源K个。
2)最大需求矩阵Max。
如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。
3)分配矩阵Allocation。
如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的数目为K。
4)需求矩阵Need。
如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。
Need[i,j]=Max[i,j]-Allocation[i,j]。
3.2银行家算法
在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。
在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁。
银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。
设进程cusneed提出请求REQUEST[i],如果REQUEST[cusneed][i],表示进程Pi需要K个Rj类型的资源。
则银行家算法按如下规则进行判断。
1)如果REQUEST[cusneed][i]<=NEED[cusneed][i],则转向步骤
(2);否则,出错,为它所需要的资源数已超过它所宣布的最大值。
2)如果REQUEST[cusneed][i]<=AVAILABLE[cusneed][i],则转向步骤(3);否则,出错,因为它所需要的资源数已超过它所宣布的最大值。
3)系统试探分配资源,修改相关数据:
AVAILABLE[i]-=REQUEST[cusneed][i];
ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];
NEED[cusneed][i]-=REQUEST[cusneed][i];
4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
5)对于某一进程i,若对所有的j,有NEED[i][j]=0,则表此进程资源分配完毕,应将占用资源释放。
根据以上步骤,所以银行家算法流程图如下所示
N
Y
Y
N
N
N
Y
Y
图1银行家算法流程图
3.3安全性检查算法
1)设置了两个变量
①工作向量Work,表示系统可提供给进程继续运行所需的各类资源数目。
开始时,Work:
=Available。
②Finish,表示系统是否有足够的资源分配给进程,使之运行完成。
开始时令Finish[i]:
=false;当有足够的资源分配给进程时,再令Finish[i]:
=true。
2)从进程集合中找到一个能满足下述条件的进程:
1Finish[i]=false;
2Need[i,j]≤Work[j];
若找到,执行步骤(3),否则,执行步骤(4)。
3)当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
Work[j]∶=Work[i]+Allocation[i,j];
Finish[i]∶=true;
gotostep2;
4)如果所有进程的Finish[i]=true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。
根据以上步骤,所以安全性检查算法流程图如下所示:
图2安全性检查算法流程图
3.4银行家算法安全性序列分析
假定系统中有五个进程{P0,P1,P2,P3,P4}和三类资源{A,B,C},各种资源的数量分别为10、5、7,在T0时刻的资源分配情况如表1所示:
表1T0时刻的资源分配表
资源情况
进程
Max
Allocation
Need
Available
ABC
ABC
ABC
ABC
P0
753
010
743
332
P1
322
200
122
P2
902
302
600
P3
222
211
011
P4
433
002
431
1)T0时刻的安全性:
表2T0时刻的安全序列
资源情况
进程
Work
Need
Allocation
Work+Allocation
Finish
ABC
ABC
ABC
ABC
P1
332
122
200
532
TRUE
P3
532
011
211
743
TRUE
P4
743
431
002
745
TRUE
P2
745
600
302
1047
TRUE
P0
1047
743
010
1057
TRUE
2)P1请求资源:
P1发出请求向量Request1(1,0,2),系统按银行家算法进行检查:
①Request1(1,0,2)≤Need1(1,2,2)
②Request1(1,0,2)≤Available1(3,3,2)
③系统先假定可为P1分配资源,并修改Available,Allocation1和Need1向量,由此形成的资源变化情况如表2所示:
表3系统先假定可为P1分配资源时刻的资源分配表
资源情况
进程
Max
Allocation
Need
Available
ABC
ABC
ABC
ABC
P0
753
010
743
230
P1
322
302
020
P2
902
302
600
P3
222
211
011
P4
433
002
431
④再利用安全性算法检查此时系统是否安全。
表4P1申请资源时的安全性检查
资源情况
进程
Work
Need
Allocation
Work+Allocation
Finish
ABC
ABC
ABC
ABC
P1
230
020
302
532
TRUE
P3
532
011
211
743
TRUE
P4
743
431
002
745
TRUE
P2
745
600
302
1047
TRUE
P0
1047
743
010
1057
TRUE
3)P4请求资源:
P4发出请求向量Request4(3,3,0),系统按银行家算法进行检查:
①Request4(3,3,0)≤Need4(4,3,1);
②Request4(3,3,0) 第三章源代码清单 3.1函数清单 工程中出现的所有自己编写的函数调用系统的重要函数,他们的函数功能都被列在这张表中了,如下表所示: 表5自己编写函数及功能形参列表 函数名 函数功能及其形参介绍 Main() 主函数,工程的入口,起点 Init() 初始化函数,用于显示程序进入时的倒计时界面。 Init2() 初始化函数,用于输入进程数目,资源种类数,每个进程最多所需的各资源数,每个进程已分配的各资源数,各个资源现有的数目。 Init3() 初始化函数,用于显示用户输入各个需要的数值后,系统刚开始各进程的资源状况。 Safe() 安全性检测算法函数。 判断系统是否处于安全状态,若处于,则给出一个安全序列。 Bank() 银行家算法函数。 用于输入用户对某个进程向系统请求资源。 对用户的请求进行资源的预分配,此时调用safe()函数进行安全性检测,若安全则对请求进行资源分配,否则请求不通过。 若是某个进程的所需要的资源为0,则系统释放它占用的资源。 表6调用系统的重要函数及功能形参列表 函数名 函数功能及其形参介绍 CreateThread( LPSECURITY_ATTRIBUTE- SlpThreadAttributes, DWORDdwStackSize, LPTHREAD_START_ROUT- INElpStartAddress, LPVOIDlpParameter, DWORDdwCreationFlags, LPDWORDlpThreadId ) Ø功能: Win32提供的创建线程的最基础的API,返 回一个HANDLE句柄。 Ø形式参数及其意义: LPSECURITY_ATTRIBUTESlpThreadAttributes: 描述安全性,用NULL表示使用缺省值。 本工程中传入null DWORDdwStackSize: 新线程拥有自己的堆栈,0表示使用缺省值1MB。 本工程中传入0。 LPTHREAD_START_ROUTINElpStartAddress: 新线程的起始地址,放线程函数名称。 本工程中传入runpress。 LPVOIDlpParameter: 此值被传送到线程函数去作为参数。 本工程中传入i,即线程编号。 DWORDdwCreationFlags: 允许产生一个暂时挂起的线程,默认是立即开始执行。 本工程中传入0。 LPDWORDlpThreadId: 新线程的ID被传到这。 本工程中传入null。 WaitForMultipleObjects( DWORDnCount, CONSTHANDLE*lpHandles, BOOLfWaitAll, DWORDdwMilliSeconds ) Ø功能: 此函数等待几个线程的激发,当所等待的 线程都激发或者时间片用尽而返回。 Ø形式参数及其意义: DWORDnCount: 表示等待几个线程。 本工程中传入m,表示用户输入的进程个数。 CONSTHANDLE*lpHandles: 输入要等待的线程的名称。 本工程中传入process[],即线程数组。 BOOLfWaitAll: 如果这个里面填入true,那么必须所有等待的线程都激发才能返回,如果填false,那么只要有一个handle激发了次函数就能返回。 本工程中传入true。 DWORDdwMilliSeconds : 如果是0,那么到这里就立刻结束了,如果是INFINITE,就无穷等待,直到,要等待的线程都激发为止。 本工程中传入NFINITE。 CreatSemaphore( LPSECURITY_ATTRIBUTES-lpAttributes, LONGlInitialCount, LONGlMaximumCount, LPCTSTRlpName, ) Ø功能: 该函数是创建一个有名或者无名信号对象。 Ø形式参数及其意义: LPSECURITY_ATTRIBUTESlpAttributes: 安全属性,NULL表示默认属性。 本工程中传入NULL。 LONGlInitialCount: 信号量的初值,必须大于等于0,小于等于所定义的最大数量。 本工程中传入0。 LONGlMaximumCount: 信号量的最大值。 本工程中传入1。 LPCTSTRlpName: 信号量的名称。 本工程中传入NULL,表示此信号量无名称。 ReleaseSemaphore( HANDLEhSemaphore, LONGlReleaseCount, ) Ø功能: 该函数用于将指定信号对象的计数增加一个指定的数量。 Ø形式参数及其意义: HANDLEhSemaphore: 需要释放的信号量的句柄。 本工程中传入Queue,表示的信号量的句柄。 LONGlReleaseCount: 信号量现值的增额,不可以是负值或是0。 本工程中传入1. LPLONGlpPreviousCount: 返回信号量原来的现值。 本工程中传入NULL。 CreateMutex( LPSECURITY_ATTRIBUTESlpMutexAttributes, BOOLbInitialOwner, LPCTSTRlpName ) Ø功能: 该函数用于创建有名或者无名的互斥对象。 Ø形式参数及其意义: LPSECURITY_ATTRIBUTESlpMutexAttributes: 安全属性。 本工程中传入NULL。 BOOLbInitialOwner: 填入TRUE表示此互斥量可以被调用。 本工程中传入FALSE。 LPCTSTRlpName: 互斥量的名称。 本工程中传入NULL。 ReleaseMutex( HANDLEhMutex ) Ø功能: 该函数放弃指定互斥对象的拥有权。 每使用一次,MUTEX引用计数自加1;每释放一次,MUTEX引用计数自减1,当引用计数减到0时,此互斥量销毁。 Ø形式参数及其意义: HANDLEhMutex: 想要释放的信号量句柄。 本工程中传入Mutex,即互斥锁的句柄。 3.2各函数的调用关系图 图是本次课程设计工程所有自己编写的函数调用系统的重要函数的函数调用关系,箭头指向某函数表示某函数被调用。 图3各函数的调用关系图 第四章运行结果测试与分析 4.1程序的正常输出结果 1)程序刚进入时的界面,5秒倒计时后进入银行家算法初始化输入。 2)初始化,输入进程数目,资源种类数,每个进程所需的各种资源,每个进程现已分配的资源数以及各资源现有数目。 3)初始化后的各进程的资源状态列表,此时系统是安全的,存在一个安全序列1->3->0->2->4。 进程1进行资源请求分配,请求资源数1,0,2。 4)第一次分配结果成功,存在一个安全序列: 1->3->0->2->4。 因为这是进程1所需资源数不为0,即NEED[1]! =0,所以系统不释放进程1的资源。 第二次分配,4号进程请求系统资源数1,2,0。 预分配后,系统进行安全性检测时,不存在一个安全序列,所以请求被拒绝。 5)进程1再次请求资源0,2,0。 存在一个安全序列1->3->0->2->4。 这时进程1的所需要的资源总数为0,即NEED[1]=0,所以系统释放进程1的资源。 6)按照一个安全序列,使所有进程都获得资源并释放资源。 4.2程序的差错控制 1)对进入银行家算法进行输入控制,输入1,0以外的字符,系统提示为非法输入,用户重新输入。 2)进程最多所需的资源数不能为负,下图为系统提示哪个进程的第几个资源输入错误。 3)进程已分配的资源数不能为负,同时已分配的资源数不能大于进程最多所需的资源数。 下图为系统提示哪个进程的第几个资源输入错误。 4)输入的资源请求不能超过系统所有资源数,以及进程所需资源数。 第五章结论与心得 本次设计中首先要解决的问题是对所做题目的理解。 简单的文字描述总是生涩难懂,像银行家算法这一问题,联系实际生活中银行贷款这一现象,再来看问题时,一切开始显得清晰,再根据书上对这个问题的描述,便可以把自己究竟该作何工作搞清楚。 明白了需求,下一个难点是如何通过软件实现。 因为这次是一个人一个题目,所以整个课程设计是自己独立完成的。 本次课程设计对银行家算法的实现不同于以往简单的模拟,需要调用Win32的API来创建线程,以及调用Win32API提供的信号量机制,实现共享数据的并发访问。 这些我以前都没有尝试过,所以一开始不知道怎么下手,这也是本次课程设计中我遇到的最大的问题。 所以在正式编程前我先着重了解了一下这些API的使用,编一些程序去实验这些API的功能作用,再进行银行家算法的编程。 了解了这些API同时也帮助自己对信号量,线程有了更深的认识。 除此之外,在程序中,我们也得强调一下对输入合法性的判断,比如,我们输入的的预申请资源的进程号没有在系统已存在的进程中,或者进程资源数不能为负数等等,我们需要对这些情况进行判断,让程序报错返回重新输入而不是因错误而中断。 通过本次课程设计,我对软件的开发的过程有了较为深入的了解,虽然只是对一个问题的简单实现,但麻雀虽小五脏俱全,我对相关问题的解决已经有了一定的认识,对软件技术这门课程也有了更为透彻的感悟。 本次课程设计,锻炼了我分析问题和解决问题的能力,为今后相关问题的解决积累了宝贵经验,也增强了自己的耐心与自信,受益匪浅。 [参考文献] 【1】严蔚敏,吴伟民.数据结构(C语言版).清华大学出版社.1997 【2】汤小丹,梁红兵,哲凤屏,汤子瀛.计算机操作系统(第三版).西安电子科技大学出版社.2010. 【3】谭浩强.C程序设计(第四版).清华大学出版社.2010.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 中南 大学 操作系统 课程设计