1、摘 要课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程.随着科学技术发展的日新日异,当今计算机应用在生活中可以说得是无处不在。因此作为二十一世纪的大学来说掌握计算机开发技术是十分重要的。通过对操作系统这门课的学习后,要求我们能够在深刻理解和应用有关经典进程的同步和互斥问题之余,能够模拟解决打瞌睡的理发师问题。要求以输出字符串的形式表示理发师和顾客的行为。理发师问题是一个利用信号量进行 P、V 操作的经典问题。设计程序实现此问题,要使得理发师的活动与顾客的活动得到各自真实的模拟。所执行的程序应体现:理发师在没有顾
2、客的时候去睡觉,有顾客则工作;顾客在理发师工作时坐下等待,无座时离开,直至等到理发师自己理发。关键字:理发师;顾客;PV 操作2目 录摘 要 11 设计要求 11.1 初始条件 11.2 技术要求 12 需求分析 22.1 具体需求 22.2 系统实现步骤 23 总体设计 33.1 总体设计思想 33.2 各功能之间的调用关系 43.3 创建数据结构 64 详细设计 .64.1 控制营业开始的模块 74.2 建立一个理发类 74.3 理发功能模块 85 系统实现原理 .156 程序运行界面 .186.1 进入程序友好界面 186.2 理发店营业界面 196.3 理发店服务界面 206.4 询问
3、是否继续工作界面 .216.5 无顾客界面 .226.6 理发店尚未营业的界面 236.7 退出程序的界面 237 设计总结 24参考文献 25致 谢 26附录 2701 设计要求1.1 初始条件(1)操作系统:Windos(2)程序设计语言:C+语言(3)设有三个理发师,3 把椅子(另外还有三把理发椅),几把椅子可用连续 存储单元。1.2 技术要求(1)为每个理发师顾客产生一个线程,设计正确的同步算法。(2)每个顾客进入理发室后,即时显示“work=1” 及其线程自定义标识,还同时显示理发室共有几名顾客及其所坐的位置。(3)为每位顾客提供一个等待沙发(4)若等待人数达到上限则新来顾客离开理发
4、店(5)若理发师理发人数达到 3 人,则可以询问理发师是否继续工作(6)若理发师工作状态为 0,则理发店关门(7)若理发师继续工作且无顾客则理发师进入睡眠状态(8)至多有 6 个顾客,每人理发至少 3 秒钟。(9)多个顾客须共享操作函数代码。(10)本操作实现并发、并行、进程同步。02 需求分析2.1 具体需求通过设计模拟解决打瞌睡的理发师问题,为理发店提供高效便捷的服务。理发店内有三名理发师,三把理发椅,和 N 把普通的椅子。要实现如果没有顾客来,那么理发师就坐在理发椅上打瞌睡;当顾客到来时,就唤醒理发师。如果顾客到来时理发师正在理发,顾客就坐下来等待。如果 N 把椅子都坐满了,顾客就离开该
5、理发店到别处去理发。理发师刚开始理发时,先看看店里有没有顾客,如果没有,则在理发椅上打瞌睡;如果有顾客,则为等待时间最长的顾客理发,且等待人数减 1。顾客来到店里,先看看有无空位,如果没有空位,就不等了。离开理发店;如果有空位则等待,等待人数加 1;如果理发师在打瞌睡,则将其唤醒。2.2 系统实现步骤这是一个很简单的程序,除了用到 main()函数之外,还用到了一个 lifa类函数来产生随机数、lifa ()、lifashi() ;另外也用到了 for 循环和 if 嵌套语句。设计的原理是:在开始程序是,先由程序员输入椅子数 chairs,然后询问程序员是否开门营业:若程序员输入y,则开门营业
6、;若输入n,则持续询问程序员是否营业。在刚开门营业之后,先随机产生顾客:若没顾客来,则理发师打瞌睡,再次进行产生顾客;若有顾客来,则直接为顾客理发。在为顾客理发期间,程序自动产生顾客,最多产生 3 个顾客。顾客进来后,先看看理发师是否在理发,是则看看是否有空椅子,若有则坐下,无则离开。如果理发师正空闲,则直接为顾客理发。当理发完成之后,先判断已经为多少人理发了,如果未超过 3 人,则继续营业。若已超过,则询问程序员是否继续营业。若继续理发,则先判断是否有人等待,若有则先为等待最久的顾客理发,若没则理发师打瞌睡,程序继续回到随机产生顾客。13 总体设计3.1 总体设计思想题目中要求描述理发师和顾
7、客的行为,本系统主要实现友好模块,以控制理发店是否开门营业。实现理发师理发模块,以控制理发师是否开始理发。实现顾客等待模块,以实现顾客是否选择等待。实现程序结束模块,以实现理发师是否停止工作以便结束程序。因此需要两类线程 lifashi()和 lifa ()分别描述理发师和顾客的行为。其中,理发师有活动有理发和睡觉两个事件;等待和理发二个事件。店里有固定的椅子数,上面坐着等待的顾客,顾客在到来这个事件时,需判断有没有空闲的椅子,理发师决定要理发或睡觉时,也要判断椅子上有没有顾客。所以,顾客和理发师之间的关系表现为:(1)理发师和顾客之间同步关系:当理发师睡觉时顾客近来需要唤醒理发师为其理发,当
8、有顾客时理发师为其理发,没有的时候理发师睡觉。(2)理发师和顾客之间互斥关系:由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有 n 把,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。(3)故引入 3 个信号量和一个控制变量:控制变量 w 用来记录等候理发的顾客数,初值为 0;控信号量 c 用来表示沙发数,初值为 3;信号量 customers 用来记录等候理发的顾客数,并用作阻塞理发师进 程,初值为 0;信号量 finish 用来记录已经完成理发的人数,并用作阻塞顾客进程,初值为 0;(4)程序只有一个主体函数,用的是几个循环体来完成理发师和顾客的各项功能。用第一个循环体实现理发
9、店是否开始营业的功能。用第二个循环体实现理发师是否开始理发的功能。在第二个循环体内设置控制程序结束的语句,可根据用户需 要而结束程序。2图 3.1 总体设计图3.2 各功能之间的调用关系(1) 友好模块是一个控制程序是否开始的循环体,用 ii 变量来控制循环体会询问用户是否开始程序。如果用户选择是,就执行后面的程序,如果选择否,就输出“对不起,理发店还没营业”,然后再次询问是否选择营业。(2)理发师的控制模块是由另一个循环模块控制的,当没有顾客光临时,就输出“没有顾客光临,理发师可以休息”。当有顾客光临时,就开始继续运行下去,按照闲则服务,忙则等待,若等待人数超过三个就离开理发店的规则运行下去
10、。当服务人数超过三个,就询问是否还要继续服务。(3)顾客等待模块,是一个判断等待条件是否成立的模块。若 c-w0,则顾客具备等待条件,否则等待条件不成立,顾客离开。输出友好界面进入控制是否营业循环进入控制理发师理发循环结束开始3T F FTFT 图 3.2 主函数流程图3.3 创建数据结构定义一个理发类,便于主程序调用。加快进程调度,提高资源利用率,创建顾客进程结束ii3创建理发师线程ii0 创建顾客进程失败4增大 CPU 吞吐量,减少内存空间。减少进程等待时间,使得程序清晰可读,处理机调用高速快捷。class lifa;int c;/沙发数int customers=0;/顾客数int co
11、unt=0;/循环中用来计量的int w=0;/等候理发的人数int finish=0;/已经理完发的人数int work1=0,work2=0,work3=0;/理发师是否在工作char opendoor;/理发店是否开门接待顾客int radom;/获取有无顾客数4 详细设计定义一个 lifa 类,便于主函数调用。线程 lifa()和 lifashi()是两个公有函数,定义私有变量 ii 用来对进程进行控制,ii0 表示理发店有顾客到来,对 A、B、C 三个理发师工作状态进行判断,若 work=1,则顾客进入等待状态,则对 c 进行判断,若 c-w0,则顾客等待。反之理发店人已满,则顾客离
12、开。若 work=0,则顾客直接进行理发不用等待。变量 customers 自增 1,等待变量 w 减 1。若 finish2 时,理发师理发人数已达到上限,询问理发师是否继续工作。jixu=“y” 则继续工作,jixu=“n” 则理发师休息。则程序结束,exit()=0。主函数开始调用,进入友好界面若 opendoor=“y”,则开门营业。若opendoor=“n”,则表示理发店尚未开门。4.1 控制营业开始的模块这个功能的实现是用了一个循环,当询问是否开始营业是,用户有两个选择,一个是,一个否,当选择是时,输出“理发店开门营业!”程序跳出该循环 进入下一个功能;当选择否时,输出“对不起,理
13、发店还没有开门”然后继续询问是否营业。5coutopendoor;while(opendoor!=y) coutopendoor;coutii;while(ii0) for(count=0;count2) /完成为 3 个人理发的任务,询问理发师是否继续工作coutjixu;if(jixu=n) cout0) /看看是否有人在等待理发 cout0) /看看是否有人在等待理发 cout0) /看看是否有人在等待理发 coutp;if(p=y)jixu=p;if(p=n)jixu=p;coutsem 减 1。若 sem 减 1 后仍大于零,则 P 原语返回,该进程继续执行。若 sem 减 1 后小
14、于零,则该进程被阻塞后进入与该信号相对应的队列 中,然后转进程调度。TF图 5.4 P 原语操作功能图sem=0调用进程入等待队列转进程调度返回Sem=sem-1入口15 V 原语操作如下:sem 加 1。若 sem 加 1 后仍大于零,则 V 原语停止执行,该进程返回调用处,继续执行。若 sem 加 1 后小于或等于零,则从该信号的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转进程调度。FT图 5.5 V 原语操作功能图唤醒等待队列中一个进程Sem=sem+1Sem2 时,已经为 3 位顾客理完发。若 opendoor=“y”,则表示理19发师继续工作且三位等待的顾客都已经理完发,
15、此时 w=0。判断 opendoor 的状态。图 6.4 询问是否继续工作的界面206.5 无顾客界面若变量 opendoor=“y”且 ii=0,则输出“没有顾客来理发,理发师坐在沙发上休息” 表示理发店开门营业,但无顾客上门。图 6.5 没有顾客来的界面216.6 理发店尚未营业的界面若 opendoor=“n”,则输出“理发店还没有开门”图 6.6 理发店尚未营业的界面6.7 退出程序的界面若 finish2 且 jixu=“n” 表示已经达到顾客数上限,理发师不在理发。则输出“谢谢光临”,退出程序。图 6.7 退出程序的界面227 设计总结为期两个星期操作系统课程设计马上就要结束了,现
16、在我来总结一下这两个星期所学的内容和感想。课程设计对学生而言是其对所学课程内容掌握情况的一次自我验证,从而有着极其重要的意义。通过课程设计能提高学生对所学知识的综合应用能力,能全面检查并掌握所学内容;计算机操作系统从课程性质上讲是一门专业基础课,它的目的和任务就是训练学生对计算机操作系统的认识,让学生对计算机操作系统有更进一部的认识,进而增加其对学习和应用相关专业课的兴趣。通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,将结论用于实践,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中当然遇到了问题
17、,可以说得是困难重重,毕竟这是不可避免的,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。由于能力有限,其中文档的编写是参考书上资料,我想在以后的学习中,要更注重实践这一环节。通过这次课程设计使我们懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到种种问题,同时在设计的过程中发现了自己的不足之处,对一些前面学过的知识理解得不够深刻,掌握得不够牢固,通过这次课程设计之后,我们把前面所学过的知识又重新温故了一遍
18、。从设计过程看,在整整两个星期的日子里,做到精益求精,学到了很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。从设计结果看,设计要求完成任务,达到了预期的目的,设计、演示效果较好。最主要是从中学到了知识。23参考文献1 郁红英,李春强.计算机操作系统.北京:清华大学出版社,20082 孟庆昌.操作系统.北京:电子工业出版社,20093 汤子瀛,哲凤屏.计算机操作系统.北京:电子工业出版社,20094 尤晋元,史美林等.windows 操作系统原理.北京:机械工业出版社,20015 孟静.计算机操作系统原理教程.北京:清华大学出版社,20056 广树建.新编 C/C+程序设计教程.广州:华南理工出版社,20087 汤子瀛,哲凤屏.计算机操作系统.西安电子科技大学学出版社.8 王清,李光明.计算机操作系统.冶金工业出版社.9 孙钟秀等. 操作系统教程. 高等教育出版社10 曾明. Linux 操作系统应用教程. 陕西科学技术出版社. 11 张丽芬,刘利雄.操作系统实验教程. 清华大学出版社.12 孟静, 操作系统教程原理和实例分析. 高等教育出版社13 周长林,计算机操作系统教程. 高等教育出版社14 张尧学,计算机操作系统教程,清华大学出版社15 任满杰,操作系统原理实用教程,电子工业出版社24致 谢25附录