您好,欢迎访问三七文档
操作系统课程设计报告书一、实现界面的接口本次课程设计总共做了四个小项目,分别是(1)CPU调度中的时间片轮转算法(2)死锁避免中的银行家算法(3)线程实现模拟超市购物(4)线城实现模拟停车场问题。把以上四个小项目整合在一块儿,把时间片轮转算法与银行家算法写在C++头文件中即可,为了使界面更加美化,可以使用#includewindows.h…..system(“Colorf0”),显示的界面如下:为了显示这个界面我在C++中使用了switchcase语句来实现界面的选择,根据用户的具体要求,来选择需要进入的项目。voidmain(){SuperMarketsuMar;intopr;while(1){cout**************菜单*****************************endl;cout**************1:CPU调度时间片轮转算法*********endl;cout**************2:死锁避免银行家算*************endl;cout**************3:线程模拟超市购物**********endl;cout**************4:PV信号量模拟停车场问题*******endl;cout***************0:结束**************endl;cout请选择要进行的操作:;cinopr;switch(opr){case1:sjp();system(pause);break;case2:cout银行家算法endl;Yhj();system(pause);break;case3:cout信号量模拟超市购物endl;srand(time(0));suMar.start();suMar.WaitForCompletion();system(pause);break;case4:cout停车endl;che();system(pause);break;case0:cout结束endl;break;}}}二、书本上的算法与代码的具体解释(1)时间片轮转法进行CPU调度代码:见书P71解释:调度程序每次把CPU分配给就绪队列首进程使用规定的时间间隔,成为时间片,本次默认设置为时间片为2,就绪队列中的每个进程轮流地运行一个时间片,当时间片耗尽时,就强迫当前运行进程让出处理器,转而排列到就绪队列尾部,等候下一轮调度。此种调度策略可以防止那些很少使用设备的进程/线程长时间地占用处理器,导致要使用设备的那些设备的那些进程/线程没有机会去启动设备。此实例在C++中进行实现,主要使用指针来实现对就绪队列、运行队列、等待队列的控制。首先使用结构体来定义进程名、运行时间、到达时间、进程状态、链接指针以及记录系统当前时间的变量,然后再分别定义建立进程的函数、判断是否有就绪进程的函数、运行进程的函数,检查就绪队列并准备运行进程的函数以及声明一个文件指。最后,在主函数调用以上函数,并在屏幕上显示出来。运行实例:例如进程1、2、3、4、5五个进程同时进入CPU,运行时间分别10、6、2、4、8.进程名到达时间运行时间1010206302404508调试结果如下:(2)银行家算法实现资源分配代码:见书P80解释:算法描述如下,假定小城镇银行家拥有资金,数量为∑,被N个客户共享,银行家对客户提出下列约束条件:1每个客户必须预先说明所要的最大资金量2每个客户每次提出部分资金量的申请并获得分配3如果银行满足客户对资金的最大需求量,那么客户在资金运作后,应在有限的时间内全部归还银行。只要客户遵守上述约束条件,银行家将保证做到:若一个客户所要的最大资金量不超过∑,银行一定会接纳此客户,并满足其资金需求;银行在收到一个客户的资金申请时,可能会因资金不足而让客户等待,但保证在有限的时间内让客户获得资金。在银行家算法中,客户可看做进程,资金可看做资源,银行家可看做操作系统。银行家算法虽然能避免死锁,但实现时受到种种限制,要求所涉及的进程不相交,即不能有同步要求,事先要知道进程的总数和每个进程请求的最大资源数,这些都很难办到。在书本上次实例代码中,需要先设定常数TASK_RUNNING为0,TASK_SUCCEED为1,TASK_WAITING为2,并将系统拥有的最大资源数为10,系统运行的最多进程数4。并定义一个类PCB(进程控制块),其中在类中,在公共类中定义p_pid,p_stat,p_apply,p_occupy,p_issuc,p_require,并定义一个构造函数pcb,在类外定义一系列子函数。最后在主函数中,输入各进程申请的资源总量,以及初始化各个进程,选择资源分配算法,判断能否满足进程的资源请求,若满足资源最大请求,进程成功完成,将其从进程队列中删除;判断能否满足进程的当前资源请求,假定对申请资源的进程分配资源,撤销模拟分配,若分配安全,可对进程进行实际的分配,归还全部系统资源,并唤醒等待进程,判断是否所有的进程都已结束。之后输入进程的当前申请量,检查系统中是否所有进程都运行结束,且当有进程释放资源时,判断是否唤醒等待资源。并设计一个算法,用于检查系统是否处于安全状态的算法,检查是否所有进程都能被设置成安全标志,若没有都设置成安全标志,则置该标志为假。实例运行结果:假设进程中有5个进程和A、B、C三类资源,在时刻T,系统资源分配情况如下:进程AllocationClaimAvailableABCABCABCP0010753332P1200322P2302902P3211222P4002433T时刻的安全序列调试结果如下:(3)线程实现模拟超市购物代码:见书P273页解释:此实例用线程控制和线程同步机制来模拟超市购物的运转情况。首先,需要创建和启动一个代表超市管理员的线程主要负责开放超市、创建各个顾客线程、关闭超市、等待所有顾客付钱离开。其次,超市管理员线程创建一个顾客线程后,等待一段时间后,在创建一个顾客,顾客主要执行等待进入超市、进行数量随机的商品选购、到熟食柜台买肉、柜台排队等待付款、离开柜台、离开超市。本例设计了3个文件,分别是vsm.cpp、vsm.h、main.cpp,其中vsm.h是基本的变量和函数的定义,vsm.cpp是核心运行部分,而main.cpp则是启动运行的一个框架。其中在头文件vsm.h中,定义最多创建的顾客数目为20,最多进入超市的顾客数目为15,各种队列的最大长度为15,随机购物时的货物种类数为5,结账柜台的个数为5,专用毫秒为1000等。并定义线程类、顾客类和超市管理员类的父类MyThread,超市线程主体SuperMarket。在vsm.cpp中,实现顾客总体的初始化,创建各个顾客线程、运行各个顾客线程、等待各个顾客线程终止、关闭各个HANDLE,并使用strand(unsignedintseed)函数。而main.cpp主要是为了可以通过调用头文件vsm.h中的函数,并在屏幕上显示。实例调试结果如下:三、自己修改后的算法及代码解释最后一个小项目是用线程来实现停车场问题,通过略微笨拙的方法来实现代码及解释如下:#includeiostream.h#includestdio.H#includewindows.hHANDLEEmpty,full,mutex;//声明3个信号量,互斥信号量mutex,计数信号量full和Emptyintx=0;inty=0;char*buffer;//缓冲区buffer//输出buffervoidoutput(){for(inti=0;i50;i++){coutbuffer[i];}cout\n;}DWORDWINAPIimport(LPVOIDparam){intj=1;do{WaitForSingleObject(Empty,INFINITE);//buffer空余量减一WaitForSingleObject(mutex,INFINITE);//形成互斥,只能一个线程去生产cout入口号为GetCurrentThreadId()&&&&&第j辆车进入停车场&&&&&&;//输出当前线程的id号,和执行的次数buffer[(y++%10)]='A';//停车赋值为Aoutput();//输出buffercoutendl;j++;ReleaseSemaphore(mutex,1,NULL);//取消互斥,允许其他线程生产ReleaseSemaphore(full,1,NULL);//可以占用车位加1}while(j!=11);//一个入口进入车辆10次return0;}DWORDWINAPIexport(LPVOIDparam){intj=1;do{WaitForSingleObject(full,INFINITE);//将占用车位减1WaitForSingleObject(mutex,INFINITE);//形成互斥访问,只能一个线程可以访问。cout出口号为GetCurrentThreadId()***第j辆车离开停车场*****;buffer[x++%10]='B';//车辆离开时赋值为Boutput();//输出buffercoutendl;j++;ReleaseSemaphore(mutex,1,NULL);//取消互斥,允许其他线程消费ReleaseSemaphore(Empty,1,NULL);//buffer空余量加1}while(j!=11);//一个出口可以通过车辆10次return0;}intche(){inti;Empty=CreateSemaphore(NULL,10,10,NULL);//声明计数信号量,Empty初值为10full=CreateSemaphore(NULL,0,10,NULL);//声明计数信号量,full初值为0mutex=CreateSemaphore(NULL,1,1,NULL);//声明互斥信号量,初值为1buffer=newchar[50];//初始化buffer数组,大小为0for(i=0;i50;i++){buffer[i]='N';}//HANDLEthread;DWORD*ThreadId=(DWORD*)malloc(2*sizeof(DWORD*));HANDLE*ThreadHandle=(HANDLE*)malloc(2*sizeof(HANDLE*));//创建线程句柄,分配空间//创建1个入口线程和1个出口线程for(i=0;i1;i++){ThreadHandle[i+1]=CreateThread(NULL,0,import,NULL,0,&ThreadId[i+1]);ThreadHandle[i]=CreateThread(NULL,0,export,NULL,0,&ThreadId[i]);}//让所有线程在主线程main()执行完钱全部执行完毕。WaitForMultipleObjects(2,ThreadHandle,TRUE,INFINITE);return0;}本代码使用两个线程来实现,一个入口线程、一个出口线程,声明3个信号量,开始设置一个互斥信号量mutex,两个计数信号量full和Empty,声明计数信号量,Empty初值为10,声明计数信号量,full初值为0,声明互斥信号量,初值为1。最后,让所有线程在主线程main()执行完钱全部执行完毕。调试结果如下:其中,A表示占用,N表示空闲,B表示车开离车库,有五十个车位,一个入口线程,一个出口线程。四、心得体会通过这次课程设计我大致了解了进程调度算法中的时间片轮转算法、银行家算法、线程调度的实现方法及他们的原理,并基于windows系统之上,将它们整合在一起,对如何整合一系列程序有了基本的了解与认识,更深层次地学习了C++语言,将本学期学习的操作系统与C++相结合,进一步了解了操
本文标题:操作系统报告
链接地址:https://www.777doc.com/doc-2308608 .html