华中科技大学操作系统实验报告

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1华中科技大学电信学院操作系统实验报告电子信息与通信学院班级:电信1202班姓名:XX学号:U2012133XX时间:2014年11月5日2实验一哲学家就餐问题一.实验目的1.熟悉哲学家就餐问题流程,编译程序,了解程序运行过程。2.理解利用设置信号量及P、V操作解决进程间的互斥这一方法,并了解其代码实现的相关方法,提炼出代码的思想(用伪代码表示)。3.对哲学家就餐问题提出新的解决方式,并简述其实现过程。二.实验原理1、问题描述有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子。每个哲学家的行为是思考,感到饥饿,然后吃通心粉。为了吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。2、分配方式方式一(不会进入死锁)仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子。这样要么一次占有两只筷子(所有线程需要的资源)进行下一步的吃通心粉,然后释放所有的资源;要么不占用资源,这样就不可能产生死锁了。方式二(会进入死锁)当筷子(资源)可用时,先分配左边的筷子,等待一会后再分配右边的筷子,由于这个过程中,左边的筷子一直没有释放,就有可能产生死锁了。3、程序运行说明程序运行过程中会弹出一个MessageBox提示操作者操作:1)第一个对话框用于选择运行模式a.选择yes表示采用的是运行的防止死锁的方式,这样的话整个程序可以一直运行下去,不会产生死锁。b.选择no表示运行产生死锁的方式会弹出第二个对话框。2)第二个对话框用于选择运行时,线程运行的时间a.选择res线程时间比较短,很快就可以死锁b.选择no线程时间跟选择yes时候的时间差不多,产生死锁的时间稍微长一点。三.实验程序流程及分析1、PhilosopherThread函数源代码DWORDWINAPIPhilosopherThread(LPVOIDpVoid){HANDLEmyChopsticks[2];intiPhilosopher=(int)pVoid;intiLeftChopstick=iPhilosopher;intiRightChopstick=iLeftChopstick+1;DWORDresult;if(iRightChopstickPHILOSOPHERS-1)//筷子编号过了5就使它为03iRightChopstick=0;//Randomizetherandomnumbergeneratorsrand((unsigned)time(NULL)*(iPhilosopher+1));//rememberhandlesformychopsticksmyChopsticks[0]=gchopStick[iLeftChopstick];//定义哲学家的左右筷子myChopsticks[1]=gchopStick[iRightChopstick];gDinerState[iPhilosopher]=RESTING;//wantschopsticksSleep(P_DELAY);for(;;){if(bWaitMultiple==FALSE){//WaituntilbothofmychopsticksareavailablegDinerState[iPhilosopher]=WAITING;//wantschopsticksPostMessage(hWndMain,WM_FORCE_REPAINT,0,0);result=WaitForSingleObject(gchopStick[iLeftChopstick],INFINITE);MTVERIFY(result==WAIT_OBJECT_0);gChopstickState[iLeftChopstick]=iPhilosopher;Sleep(P_DELAY/4);gDinerState[iPhilosopher]=WAITING;//wantschopsticksPostMessage(hWndMain,WM_FORCE_REPAINT,0,0);result=WaitForSingleObject(gchopStick[iRightChopstick],INFINITE);MTVERIFY(result==WAIT_OBJECT_0);gChopstickState[iRightChopstick]=iPhilosopher;}else{//WaituntilbothofmychopsticksareavailablegDinerState[iPhilosopher]=WAITING;//wantschopsticksPostMessage(hWndMain,WM_FORCE_REPAINT,0,0);result=WaitForMultipleObjects(2,myChopsticks,TRUE,INFINITE);MTVERIFY(result=WAIT_OBJECT_0&&resultWAIT_OBJECT_0+2);gChopstickState[iLeftChopstick]=iPhilosopher;gChopstickState[iRightChopstick]=iPhilosopher;}//Philosophercannoweatagrainofrice4gDinerState[iPhilosopher]=EATING;//philosopheriseatingPostMessage(hWndMain,WM_FORCE_REPAINT,0,0);Sleep(P_DELAY);//PutdownchopsticksgDinerState[iPhilosopher]=RESTING;//philosopherisrestinggChopstickState[iRightChopstick]=UNUSED;gChopstickState[iLeftChopstick]=UNUSED;PostMessage(hWndMain,WM_FORCE_REPAINT,0,0);MTVERIFY(ReleaseMutex(gchopStick[iLeftChopstick]));//释放筷子资源MTVERIFY(ReleaseMutex(gchopStick[iRightChopstick]));//PhilosophercannowmeditateSleep(P_DELAY);}//endforreturn0;}2、伪代码对于每一个哲学家来说,他们需要抢占的临界资源就是左右的两支筷子。如下写出两种分配资源方式的算法:(1)不发生死锁的方式(要么一下占用两支筷子,要么不占用)varmutexleftchopstick,mutexrightchopstick;beging:resting;waiting;p(mutexleftchopstick);p(mutexrightchopstick);GetResource(leftchopstick,rightchopstick);eating;v(mutexleftchopstick);v(mutexrightchopstick);end(2)发生死锁的方式(一旦可以占用筷子,就马上占用)varmutexleftchopstick,mutexrightchopstick;beging:resting;waiting;p(mutexleftchopstick);GetResource(leftchopstick);p(mutexrightchopstick);GetResource(rightchopstick);eating;5v(mutexleftchopstick);v(mutexrightchopstick);end3、代码运行结果(1)选择Y,程序正常运行,如下图所示:(2)选择N,程序进入死锁,如下图所示:64.代码分析:1)在本代码中,为了防止死锁,先确定两只筷子均没被占用才获取筷子,这样就打破了死锁的必要条件中的循环等待条件。2)在本代码中,想要发生死锁,只需要在有一根筷子时即占用。这样由于资源不可抢占且不可剥夺,因此很容易形成一个循环等待队列,因而产生死锁。四、思考题:其他解决死锁的方案:方案一:至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,并释放出他所使用过的两支筷子,从而可使更多的哲学家进餐。将room作为信号量,只允许4个哲学家同时就餐,这样就能保证至少有一个哲学家可以就餐,而申请就餐的哲学家进入room的等待队列,根据FIFO的原则,总会进入到餐厅就餐,因此不会出现饿死和死锁的现象。伪码如下:semaphorechopstick[5]={1,1,1,1,1};semaphoreroom=4;voidphilosopher(inti){while(true){Think();wait(room);//请求进入房间进餐wait(chopstick[i]);//请求左手边的筷子wait(chopstick[(i+1)%5]);//请求右手边的筷子eat();signal(chopstick[(i+1)%5]);//释放右手边的筷子signal(chopstick[i]);//释放左手边的筷子signal(room);//退出房间释放信号量room}}方案二:规定奇数号哲学家先拿起他左边的筷子,然后再去拿右边的筷子;而偶数号的哲学家则相反。因此,会有1、2号哲学家竞争1号筷子,3、4号哲学家竞争3号筷子,五个哲学家都先竞争奇数号筷子,再去竞争偶数号筷子,最后总会有一个哲学家能获得两支筷子而进餐。而申请不到的哲学家进入阻塞等待队列,根FIFO原则,不会出现饿死的哲学家。伪码如下:semaphorechopstick[5]={1,1,1,1,1};voidphilosopher(inti){while(true){think();if(i%2==0)//偶数哲学家,先右后左。{7wait(chopstick[i+1]mod5);wait(chopstick[i]);eat();signal(chopstick[i+1]mod5);signal(chopstick[i]);}else//奇数哲学家,先左后右。{wait(chopstick[i]);wait(chopstick[i+1]mod5);eat();signal(chopstick[i]);signal(chopstick[i+1]mod5);}}五、实验总结:通过本次实验,我对哲学家就餐问题加深了理解,明白了设计程序时如果考虑不周,就有可能出现死锁饥饿等现象。本次实验也帮助我增强了阅读C语言的能力,尽管老师已经详细解释了这个哲学家就餐问题的算法思路,伪代码也能够看懂,但具体到用源代码实现时,我们的编程能力往往满不足了独立设计程序的需要。这要求我们加强课外的学习,提高自己的实践能力。从这次实验中,我也看到解决死锁的方案有多种,并不止源代码给出的那一个方案。这给我们启发:探索永无止境。我们面对新的问题时,一定要勤于思考,开动脑筋,这样才能找到一个保证效率与稳定性的解决问题之道。8实验二阅读者和写入者问题一、实验目的:1、巩固VC++6.0的使用,调试并正确运行程序。2、理解阅读者和写入者中出现的问题,掌握信号量在处理这类问题中起到的作用。理解源代码如何实现对阅读者和写入者权限的管理。3、编译源程序,熟悉窗口操作。4、写出ReaderThread()和WriterThread()函数伪码,并完成思考题二、实验原理:1、问题描述:有一个公用的数据集,有很多人需要访问,其中一些需要阅读其中的信息,一些需要修改其中的消息。阅读者可以同时访问数据集,而写入者只能互斥的访问数据集,不能与任何的进程一起访问数据区。2、源程序算法实现调度说明:程序中,实现读者优先的原则,即当有读者等待时,优先使读者读消息,等到读者阅读完成后再进行写入操作(不可同时读出和写入,但可以同时多用户读出)。当同时又写入和读出等待时,同样先执

1 / 11
下载文档,编辑使用

©2015-2020 m.111doc.com 三一刀客.

备案号:赣ICP备18015867号-1 客服联系 QQ:2149211541

×
保存成功