哲学家就餐问题报告
6个哲学家进餐问题预防死锁
红河学院课程设计报告操作系统课程名称:6个哲学家进餐设计题目:院系:工学院专业:计算机科学与技术班级:11计科班曹永前设计者:学号:201101030466指导教师:韦相2013 年 5 月26 日1. 问题描述:一个房间内有6个哲学家,他们的生活就是思考和进食。
哲学家思考后,过一定的时间就会饥饿,饥饿之后就想吃饭,吃饭后再思考。
房间里有一张圆桌,桌子周围放有五把椅子,分别属于五位哲学家每两位哲学家之间有一把叉子,哲学家进食时必须同时使用左右两把叉子。
2. 问题分析1、写出哲学家进餐的算法描述。
用六只筷子解决需要用两双筷子来进餐的六个哲学家,由于每个哲学家都需要其周围的两只筷子,所以筷子是公用信号量,这久需要设置一个互斥信号量,来使六个哲学家互斥的进餐.具体做法将六个信号量设置为0-5,用pv 源于来控制信号量,并将六个哲学家分别编号为0-5.经过仔细分析我们会发现,有这样一个问题存在,就是当每个哲学家都申请到他周围的一只筷子时,由于他们每人都只有一只筷子无法进餐,没有进餐他们就无法释放他们已经得得到的筷子,这样是进餐出于一种僵局,无法继续下去,这就是死锁问题.2、死锁问题的分析与具体的解决方法。
死锁问题就是当每个哲学家都拿到且只拿到一只筷子,这样每个哲学家都无法进餐,也无法释放所得到的筷子,所以解决死锁我们就要从这入手,就是怎样去预防使所有哲学家不要同时去申请他们同一方向的筷子.根据这解决死锁的方法有以下几种:a.每一次最多只能有五个哲学家申请进餐.这样其中的一个哲学家就能申请到两只筷子,就能够进餐,再将筷子释放给其他哲学家进餐.b.用AND信号量,就是哲学家需同时申请其左右两边的筷子,两边都有资源的时候,才能让这个哲学家得到资源,这样哲学家只要申请到筷子就能进餐, 再将筷子释放给其他哲学家进餐.c.用管程机制来实现。
d.我们前面已经将每个哲学家都分配了一个编号,我们可以编号为奇数的哲学家首先去申请其左边的筷子,再去申请其右手边的筷子;让编号为偶数的哲学家,先去申请其右边的筷子,再去申请其左边的筷子.我们可以看出编号为奇数的哲学家左边,与编号为偶数的哲学家的右边为同一只筷子,当其中一个哲学家拿到此筷子后,他另一边的筷子也是空闲的,这样就能避免死锁.主程序中我使用的是最后一种避免死锁的方法.3、用C程序实现哲学家进餐。
哲学家进餐问题的趣味例子
哲学家进餐问题的趣味例子
哲学家进餐问题是一个经典的计算机科学问题,用来展示并发编程中可能出现
的资源竞争和死锁问题。
这个问题的描述是:五位哲学家围坐在一张圆桌前,每位哲学家面前有一碗意面,但他们之间共享一把只能被一个人同时使用的餐叉。
每位哲学家需要先拿起右手边的餐叉,再拿起左手边的餐叉才能吃饭,吃完后放下餐叉继续思考问题。
如果哲学家之间同时试图拿起自己左右手边的餐叉,就会导致死锁问题,无法继续进餐。
这个问题的趣味例子在于通过这种抽象的场景,展现了并发编程中常见的竞争
和死锁问题。
实际上,哲学家进餐问题也可以被看作是对资源管理和同步机制的一种考验。
如果每位哲学家都按照固定的顺序拿餐叉,就不会发生死锁;而如果哲学家们都随机地尝试拿餐叉,就可能会出现资源竞争的问题,导致无法进餐。
这个问题的趣味之处在于,通过一个简单的场景,展示了复杂的并发编程中可
能出现的问题,让人们更加深入地理解并发编程中的挑战和技巧。
通过哲学家进餐问题的讨论,人们可以思考如何设计合理的同步机制和资源管理策略,避免竞争和死锁问题的发生,提高程序的并发性能和稳定性。
总的来说,哲学家进餐问题是一个充满趣味和启发的例子,能够帮助人们更好
地理解并发编程中的难点,同时也能够激发人们对于解决问题的创造力和思考能力。
通过这个例子的讨论,人们可以不仅仅学到技术知识,更能够培养出解决问题的能力和思维方式,为未来的学习和工作打下坚实的基础。
愿每位哲学家都能够顺利进餐,思考问题,探索未知的世界。
哲学家就餐问题实验报告
南昌大学实验报告学生姓名:倪焕学号:8000114018 专业班级:软件工程141班实验类型:■验证□综合□设计□创新实验日期:2016.5.24 实验成绩:一、实验项目名称哲学家就餐问题二、实验目的利用PV操作解决哲学家就餐问题三、软硬件环境软件:Visual Studio2010硬件:PC机一台四、实验内容结果//哲学家就餐问题的解法#include <windows.h>#include <process.h>#include <stdlib.h>#include <stdio.h>#include <iostream>using namespace std; //命名空间std内定义的所有标识符都有效const unsigned int PHILOSOPHER_NUM=5; //哲学家数目const char THINKING=1; /*标记当前哲学家的状态,1表示等待,2表示得到饥饿,3表示正在吃饭*/const char HUNGRY=2;const char DINING=3;HANDLE hPhilosopher[5]; //定义数组存放哲学家/*HANDLE(句柄)是windows操作系统中的一个概念。
指的是一个核心对象在某一个进程中的唯一索引*/HANDLE semaphore[PHILOSOPHER_NUM]; // semaphore 用来表示筷子是否可用HANDLE mutex; // Mutex用来控制安全输出DWORD WINAPI philosopherProc( LPVOID lpParameter) //返回DWORD(32位数据)的API 函数philosopherProc{int myid; //哲学家idchar idStr[128];char stateStr[128];char mystate;int ret;unsigned int leftFork; //左筷子unsigned int rightFork; //右筷子myid = int(lpParameter);itoa(myid, idStr, 10);WaitForSingleObject(mutex, INFINITE);cerr << "philosopher " << myid << " begin......" << endl;ReleaseMutex(mutex);mystate = THINKING; //初始状态为THINKING leftFork = (myid) % PHILOSOPHER_NUM;rightFork = (myid + 1) % PHILOSOPHER_NUM;while (true){switch(mystate){case THINKING:mystate = HUNGRY; // 改变状态strcpy(stateStr, "HUNGRY");break;case HUNGRY:strcpy(stateStr, "HUNGRY");ret = WaitForSingleObject(semaphore[leftFork], 0); // 先检查左筷子是否可用if (ret == W AIT_OBJECT_0){ret = WaitForSingleObject(semaphore[rightFork], 0); //左筷子可用就拿起,再检查右筷子是否可用if (ret == WAIT_OBJECT_0){mystate = DINING; // 右筷子可用,就改变自己的状态strcpy(stateStr, "DINING");}else{ReleaseSemaphore(semaphore[leftFork], 1, NULL); // 如果右筷子不可用,就把左筷子放下}}break;case DINING:// 吃完后把两支筷子都放下ReleaseSemaphore(semaphore[leftFork], 1, NULL);ReleaseSemaphore(semaphore[rightFork], 1, NULL);mystate = THINKING; // 改变自己的状态strcpy(stateStr, "THINKING");break;}// 输出状态WaitForSingleObject(mutex, INFINITE);cerr << "philosopher " << myid << " is : " << stateStr << endl;ReleaseMutex(mutex);Sleep(5000);}}int main(){int i,run;run = 1;mutex = CreateMutex(NULL, false, NULL);for (i=0; i<PHILOSOPHER_NUM; i++){semaphore[i] = CreateSemaphore(NULL, 1, 1, NULL); //创建一个新的信号量hPhilosopher[i]=CreateThread(NULL,0,philosopherProc,LPVOID(i),CREATE_SUSPENDED,0); //创建一个新线程ResumeThread(hPhilosopher[i]); //线程恢复函数Sleep(15);}while(run){Sleep(5000);cerr<<"**************************************"<<endl;}return 0; }五、实验体会通过本次实验,首先是对哲学家就餐问题有了更深的了解,而通过PV操作,很好的解决了哲学家就餐问题,这使得我对PV操作更加熟悉,同时帮助我理解了原先不太懂的地方,希望强加练习。
实验一 哲学家就餐问题
实验一哲学家就餐问题一、实验目的1.熟练使用VC++6.0编译环境,调试并正确运行程序。
2.熟悉哲学家就餐问题流程。
3.理解哲学家就餐问题中出现的问题,进而掌握死锁的必要条件。
4.熟悉源程序中产生和防止死锁的算法,及其相关窗口操作。
二、实验原理1.问题描述:有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子,每个哲学家的行为时思考,饥饿,然后吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边取筷子。
2.防止死锁发生的分配方式:仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子。
这样要么一次占有两只筷子(所有线程需要的资源)进行下一步吃通心粉,然后释放所有的资源;要么不占用资源,这样就不可能产生死锁了。
3.产生死锁的分配方式:当筷子(资源)可用时,先分配左边的筷子,等待一会后再分配右边的筷子,由于这个过程中,左边的筷子一直没有释放,就可能产生死锁了。
4.程序运行说明:程序运行过程中会弹出一个MessageBox提示操作者操作:1)第一个对话框用于选择运行模式a.选择yes表示采用的是运行的防止死锁的方式,这样的话整个程序可以一直运行下去,不会产生死锁。
b.选择no表示运行产生死锁的方式会弹出第二个对话框。
2)第二个对话框用于选择运行时,线程运行的时间a.选择yes线程时间比较短,很快就可以死锁。
b.选择no线程时间跟选择yes时的时间差不多,产生死锁的时间稍微长一点。
三、实验过程及分析1.PhilosopherThread(LPVOID pVoid)函数伪代码1)不死锁方式Var mutexleftchopstick,mutexrightchopstick;Beging:Resting;Waiting;P{mutexleftchopstick};P{mutexrightchopstick};GetResource{leftchopstick,rightchopstick};Eating;V{mutexleftchopstick};V{mutexrightchopstick};End2)发生死锁方式Var mutexleftchopstick,mutexrightchopstick;Beging:Resting;Waiting;P{mutexleftchopstick};GetResource{leftchopstick};P{mutexrightchopstick};GetResource{rightchopstick};Eating;V{mutexleftchopstick};V{mutexrightchopstick};End2.代码分析1)不发生死锁时,哲学家迅速同时抢占两个筷子的资源,而若是不能同时抢占两只筷子则继续等待,知道有两只筷子空闲则抢占,这样就打破了死锁的必要条件。
五个哲学家吃饭问题详细解答
五个哲学家吃饭问题详细解答在一个阳光明媚的下午,五个哲学家聚在一起,准备享用一顿丰盛的午餐。
听起来很简单吧?但实际上,这顿饭可没那么容易!让我们来看看这群头脑发达的哲学家是如何在吃饭问题上纠结的。
1. 场景设定1.1 哲学家的基本设定这五位哲学家,一个比一个聪明。
他们分别是苏格拉底、柏拉图、康德、尼采和海德格尔。
你可以想象,他们脑袋里装的全是复杂的哲学思想,而不是食物的搭配。
所以,当这五位坐下来,面对一桌子美味的食物时,事情就开始变得有趣了。
1.2 吃饭的挑战问题来了:他们每个人都必须遵守一个规则——不可以同时吃饭,得轮流。
你想想,五个哲学家加上一个轮流吃饭的规则,这可真是“见鬼了”的挑战!想要吃上一口美味的菜,简直比推理一个哲学命题还难。
他们轮流吃饭的原则,真是把这顿饭变成了一场智力的较量。
2. 各自的哲学观2.1 苏格拉底的理性苏格拉底首先站出来,他一边抚摸着自己的胡须,一边说:“吃饭嘛,首先得用理性来解决问题。
”他鼓励大家先讨论,谁应该先吃,谁应该后吃。
他认为,只有通过理性对话,才能达到最佳的吃饭方案。
可是,你能想象吗?这一讨论持续了整整一个小时,食物都快冷掉了!2.2 柏拉图的理想接着柏拉图出场,他满脸严肃地说:“我们要追求理想的吃饭方式。
”他想出了一个绝妙的主意:每个人都应该依照自己的德性来决定吃的顺序。
结果,大家一顿争论,谁的德性更高?苏格拉底说他是智者,康德坚持说自己是道德之父,而尼采则跳出来,吼着“超人才能吃超好的饭!”搞得大家乱成一团,吃的机会又飞了。
3. 饥饿的对抗3.1 食物的诱惑这时,桌子上的食物开始散发出诱人的香气,真是令人垂涎欲滴。
五位哲学家每个人的肚子都开始抗议,仿佛在唱着“我们要吃饭”的歌。
吃饭这件事,从理性讨论变成了一场生存竞争。
每个人都在默默地想着:“快点!要是再不吃,我的哲学思想就要被饿死了!”3.2 轮流的尴尬最终,他们决定采取轮流吃饭的方式。
可当轮到康德的时候,他又开始喋喋不休,讲起了“绝对命令”的哲学,让其他人都想打瞌睡。
哲学家进餐问题
哲学家进餐问题1.问题描述:哲学家进餐问题描述有五个哲学家,他们的生活方式是交替地进行思考和进餐,哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,平时哲学家进行思考,饥饿时便试图取其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,该哲学家进餐完毕后,放下左右两只筷子又继续思考。
约束条件(1)只有拿到两只筷子时,哲学家才能吃饭。
(2)如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子。
(3)任一哲学家在自己未拿到两只筷子吃完饭前,不会放下手中已经拿到的筷子。
2.求解方法(1).信号量的设置放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用,为了实现对筷子的互斥访问,可以用一个信号量表示筷子,由这五个信号量构成信号量数组。
semaphore chopstick[5] = {1,1,1,1,1};while(true){/*当哲学家饥饿时,总是先拿左边的筷子,再拿右边的筷子*/wait(chopstick[i]);wait(chopstick[(i+1)%5]);// 吃饭/*当哲学家进餐完成后,总是先放下左边的筷子,再放下右边的筷子*/signal(chopstick[i]);signal(chopstick[(i+1)%5]);}上述的代码可以保证不会有两个相邻的哲学家同时进餐,但却可能引起死锁的情况。
假如五位哲学家同时饥饿而都拿起的左边的筷子,就会使五个信号量chopstick都为0,当他们试图去拿右手边的筷子时,都将无筷子而陷入无限期的等待。
(2)避免死锁策略一原理:至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释放出他所使用过的两支筷子,从而可使更多的哲学家进餐。
定义信号量count,只允许4个哲学家同时进餐,这样就能保证至少有一个哲学家可以就餐。
semaphore chopstick[5]={1,1,1,1,1};semaphore count=4; // 设置一个count,最多有四个哲学家可以进来void philosopher(int i){while(true){think();wait(count); //请求进入房间进餐 当count为0时 不能允许哲学家再进来了wait(chopstick[i]); //请求左手边的筷子wait(chopstick[(i+1)%5]); //请求右手边的筷子eat();signal(chopstick[i]); //释放左手边的筷子signal(chopstick[(i+1)%5]); //释放右手边的筷子signal(count); //退出房间释放信号量}}策略二原理:仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子进餐。
操作系统哲学家就餐问题实验报告
include <>include <>include <string>include <iostream>include <>using namespace std;bool tools5; //全局变量,用餐工具CRITICAL_SECTION cs; //信号量, 在线程中使用,临界区class Philosopher{private:int number;int status; /标记当前哲学家的状态,0表示正在等待即处于饥饿状态,1表示得到两支筷子正在吃饭,2表示正在思考/ public:Philosopherint num=0: status2, numbernum { }const int find{return number;}const int getinfo{ return status; }void Change ; //状态改变函数void dead_lock;};/////////void Philosopher::dead_lock{EnterCriticalSection &cs ; //进入临界区 string s;ifstatus==1{toolsnumber%5=true;// toolsnumber-1%5=true;status=2;}else ifstatus==2{status=0;//toolsnumber-1%5=false;//toolsnumber-1%5=true;}else ifstatus==0{toolsnumber%5=false;toolsnumber-1%5=false;status=1;}LeaveCriticalSection &cs ;// cout<<"";}/////////void Philosopher::Change{EnterCriticalSection &cs ; //进入临界区 ifstatus==1 //正在进餐{toolsnumber%5=true; //放下左手工具 toolsnumber-1%5=true; //放下右手工具 status=2; //改变状态为思考}else ifstatus==2 //思考中{status=0; //改变状态为等待}else ifstatus==0 //等待中{iftoolsnumber%5&&toolsnumber-1%5 //左右手两边工具均为空闲状态{toolsnumber%5=false; //拿起左手工具toolsnumber-1%5=false; //拿起右手工具status=1;}}LeaveCriticalSection &cs ;}string printPhilosopher pA{//pA->Change;int i=pA->getinfo;string str;ifi==0str="等待";else ifi==1str="就餐";else str="思考";return str;}string toolstatusbool a{string state;ifa==truestate="闲";ifa==falsestate="用";return state;}int main{char con='y'; //判断是否继续// con = 'n';forint i=0;i<5;i++toolsi=true; //筷子都未使用,初始化Philosopher P11,P22,P33,P44,P55;InitializeCriticalSection &cs ; //初始化初始化临界区cout<<"-----------------------状态说明示意图:-----------------------"<<endl;cout<<" "<<"哲学家1号的状态"<<" "<<endl;cout<<" 筷子0的状态"<<" "<<"筷子1的状态"<<endl;cout<<"哲学家5号的状态"<<" "<<"哲学家2号的状态"<<endl;cout<<" 筷子4的状态"<<" "<<"筷子2的状态"<<endl;cout<<" 哲学家4号的状态"<<" "<<"哲学家3号的状态"<<endl;cout<<" "<<"筷子3的状态"<<endl;//cout<<" "<<"哲学家3号的状态"<<" "<<endl;cout<<"筷子的状态,用表示使用中,闲表示空闲中;"<<endl;cout<<"--------------------------------------------------------------"<<endl ;//cout<<"哲学家们开始生活:"<<endl;//cout<<"当前状态:";cout<<endl;//cin>>con;whilecon=='y'{; ; ; ; ;cout<<"当前状态为:"<<endl;cout<<" "<<<<print&P1<<" "<<endl;cout<<" "<<toolstatustools0<<" "<<toolstatustools1<<endl;cout<<" "<<<<print&P5<<" "<<<<print&P2<<endl;cout<<" "<<toolstatustools4<<" "<<toolstatustools2<<endl;cout<<" "<<<<print&P4<<" "<<<<print&P3<<endl;cout<<" "<<toolstatustools3<<endl;cout<<"--------------------------"<<endl;cout<<"若要继续下一状态,输入y;输入n进入死锁;输入其他,结束程序:";cin>>con;Sleep20;}whilecon=='n'{;; ; ; ;cout<<"死锁情况"<<endl;cout<<" "<<<<print&P1<<" "<<endl;cout<<" "<<toolstatustools0<<" "<<toolstatustools1<<endl;cout<<" "<<<<print&P5<<" "<<<<print&P2<<endl;cout<<" "<<toolstatustools4<<" "<<toolstatustools2<<endl;cout<<" "<<<<print&P4<<" "<<<<print&P3<<endl;cout<<" "<<toolstatustools3<<endl;cout<<"--------------------------"<<endl;cout<<"输入n继续;输入其他,结束程序:";cin>>con;Sleep20;}DeleteCriticalSection &cs ; //退出资源区return 0;}。
哲学家进餐问题
05611 贺美琛 冯文中
问题描述
设有五个哲学家,共用一张放有五把椅子 的餐桌,每人坐在一把椅子上,桌子上有五个 碗和五只叉子,每人两边各放一只叉子。哲学 家们是交替思考和进餐,饥饿时便试图取其左 右最靠近他的叉子。
(1) 只有拿到两只叉子时,哲学家才能吃饭。 (2) 如果叉子已被别人拿走,则必须等别人吃完之后才能拿 到叉子。
算法 C思想:
仅当哲学家的左右两支叉子都可用时, 才允许他拿起叉子进餐。
方法1:利用AND 型信号量机制实现 方法2:利用信号量mutex的保护机制实现
方法1
在一个原语中,将一段代码同时需 要的多个临界资源,要么全部分配给它, 要么一个都不分配,因此不会出现死锁 的情形。当某些资源不够时阻塞调用进 程;由于等待队列的存在,使得对资源的 请求满足FIFO 的要求,因此不会出现饥 饿的情形。
算法改善:
至多只允许四个哲学家同时进餐,以保 证至少有一个哲学家能够进餐,最终总会释 放出他所使用过的两支叉子,从而可使更多 的哲学家进餐。
改进后的算法A
semaphore fork[5]={1,1,1,1,1}; semaphore room=4; void philosopher(int i) { while(true) { think(); wait(room); //请求进入房间进餐 wait(fork[i]); //请求左手边的叉子 wait(fork[(i+1)%5]); //请求右手边的叉子 eat(); signal(fork[(i+1)%5]); //释放右手边的叉子 signal(fork[i]); //释放左手边的叉子 signal(room); //退出房间释放信号量room } }
操作系统实验报告哲学家就餐
操作系统实验报告哲学家就餐一、实验目的:通过模拟哲学家就餐问题,了解并掌握操作系统中的进程同步机制,以及解决进程间资源竞争所引发的死锁问题。
二、实验介绍:哲学家就餐问题是由荷兰计算机科学家伊克斯特拉(Dijkstra)于1965年首次提出的。
其问题描述如下:五位哲学家坐在一张圆桌子周围,每个哲学家面前有一碗饭和一根筷子。
哲学家的生活方式是交替地进行思考和进食。
当一个哲学家思考时,他不需要使用他的两个筷子;当一个哲学家想吃饭时,他需要同时获取他的左右两个筷子,并在获取到筷子后才能开始进食。
问题的关键是如何解决哲学家间的筷子竞争问题,以及避免死锁的发生。
三、实验设计:1.并发思路每个哲学家作为一个进程,在进行思考和进食这两个操作之前,需要获取他的两个筷子。
接下来考虑进程同步的两个关键点:-互斥:保证每个筷子同时只能被一个哲学家使用,避免资源竞争问题。
-死锁避免:通过限制只允许至多四位哲学家同时持有筷子,从而避免死锁发生。
2.进程同步机制- 互斥:使用Semaphore实现互斥,每个筷子都是一个Semaphore,初始值为1-死锁避免:引入一个全局计数器,记录当前持有筷子的哲学家数量,每次哲学家想要获取筷子时,先检查该计数器,仅当计数器小于4时才会获取筷子。
四、实验步骤:1.创建5个哲学家进程和5个筷子线程。
2.每个哲学家的线程循环执行思考和进食操作。
3.在进食之前,哲学家需要获取两个筷子,获取筷子的顺序按照哲学家编号进行,每个哲学家先获取自己的左边筷子,再获取自己的右边筷子。
4.进行进食操作后,哲学家释放两个筷子。
5.循环执行步骤3和步骤4,直到实验结束。
五、实验结果:通过观察实验结果,可以看到哲学家的思考和进食操作交替进行,并且避免了死锁的发生。
六、实验总结:通过本次实验,我了解了操作系统中的进程同步机制,并学会了如何解决资源竞争和死锁问题。
在本实验中,我使用了Semaphore和全局计数器实现了互斥和死锁避免,从而成功模拟了哲学家就餐问题。
哲学家就餐问题解决死锁的三种思路
哲学家就餐问题是计算机科学中一个经典的同步问题,它描述了五位哲学家围坐在圆桌前就餐,每位哲学家必须先拿起右边的餐具再拿起左边的餐具,但每次只能有一位哲学家拿起餐具就餐。
这个问题的关键在于如何避免死锁,即所有哲学家都拿起了右边的餐具,然后等待拿左边餐具的哲学家放下右边的餐具。
为了解决这个问题,计算机科学家提出了三种思路。
第一种思路是引入一个“服务生”,服务生负责给哲学家提供餐具,每次只允许一个哲学家向服务生请求餐具,这样就可以避免死锁。
然而,这种方法可能会引入新的竞争条件,服务生可能会成为新的瓶颈,从而降低系统的效率。
第二种思路是引入资源分级,为了避免死锁,可以给每个哲学家的餐具加上编号,要求哲学家先拿编号较小的餐具,再拿编号较大的餐具。
这样就可以避免死锁,但是可能会增加系统的复杂性,需要管理更多的资源状态。
第三种思路是破坏死锁的四个必要条件之一。
死锁发生的四个必要条件分别是互斥、请求并持有、不可剥夺和循环等待。
为了避免死锁,可以破坏其中一个或多个条件。
可以引入超时机制,当哲学家拿到一个餐具后,一定时间内没有获得另一个餐具,就放下手中的餐具,避免形成循环等待。
这种方法可以在不增加系统复杂性的情况下有效地解决死锁问题。
在我看来,这三种思路各有优缺点,要根据具体的场景和需求选择合适的方法。
不同的问题可能需要采用不同的思路来解决,需要权衡各种因素来做出最佳的决策。
哲学家就餐问题是一个充满哲学思考的经典问题,它不仅考察了计算机科学中的同步与互斥问题,更可以引发我们对于资源分配、竞争条件和系统设计的深入思考。
通过对哲学家就餐问题的深入理解,我们可以更加灵活地运用不同的思路解决实际中的问题,让我们的系统更加健壮和高效。
结语:通过对哲学家就餐问题的深入探讨,我们可以发现在计算机科学中,解决死锁问题有很多种思路,每种思路都有其独特的优缺点。
只有充分理解这些思路并根据具体情况做出权衡,才能更好地解决实际中遇到的死锁问题。
哲学家吃饭问题 实验报告 操作系统
欢迎共阅目录1.设计题目与要求 (2)1.1设计目的1.2设计要求2.总体设计思想与相关知识 (2)2.1总体设计思想2.2问题描述2.3解决方案3.数据结构、流程图 (2)3.1数据结构3.2流程图4.源代码 (3)5.运行结果 (6)6.结果分析 (7)7.总结及心得体会 (7)1.设计题目与要求1.1设计目的掌握进程同步问题的解决思路及方法,熟练使用Windows操作系统提供的信号量机制解决各种进程同步问题。
1.2设计要求设有五个哲学家,共用一张放有五把椅子的餐桌,每人坐在一把椅子上,桌子上有五个碗和五只筷子,每人两边各放一只筷子。
哲学家们是交替思考和进餐,饥饿时便试图取其左右最靠近他的筷子。
条件:(1) 只有拿到两只筷子时,哲学家才能吃饭。
(2) 如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子。
(3) 任意一个哲学家在自己未拿到两只筷子吃饭前,不会放下手中拿到的筷子。
2.总体设计思想与相关知识2.1总体设计思想哲学家的生活就是思考和吃饭,即思考,饿了就餐,再思考,循环往复。
要求是:每一个哲学家只有在拿到位于他左右的筷子后,才能够就餐;哲学家只能先拿左边的筷子,再去拿右边的筷子,而不能同时去抓他两边的筷子,也不能从其他哲学家手中抢夺筷子;哲学家每次就餐后必须放下他手中的两把筷子后恢复思考,不能强抓住餐具不放。
设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上餐具的使用情况。
即设计一个能安排哲学家正常生活的程序。
2.2问题描述可能出现死锁问题,因为当五个哲学家都饥饿时,都拿着一支筷子,这样就可能五个哲学家都用不上餐。
2.3解决方案2.3.1 最多允许4个哲学家同时坐在桌子周围。
2.3.2 给所有哲学家编号,奇数号的哲学家必须首先拿左边的筷子,偶数号的哲学家则反之。
2.3.3 为了避免死锁,把哲学家分为三种状态,思考,饥饿,进食,仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子,并且一次拿到两只筷子,否则不拿。
哲学家就餐问题(进程管理)
进程管理一、设计目的、功能与要求设计目的:掌握进程管理的相关内容,对进程的同步和互斥,及信号量机制有深入的理解实验内容:模拟实现用信号量机制解决哲学家就餐问题具体要求:任选一种计算机高级语言编程实现实现5个哲学家(5只筷子)的顺利就餐需避免出现死锁使用信号量、及信号量的等待队列使用P操作、V操作能够显示每个哲学家、及每只筷子的状态二、问题的详细描述、需求分析该实验要求模拟实现用信号量机制解决哲学家就餐问题。
哲学家就餐问题详细描述如下:有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子,即共5只筷子。
每个哲学家的行为是思考和进餐。
每个哲学家的行为是思考和进餐。
为了进餐,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。
思考时则同时将两支筷子放回原处时则同时将两支筷子放回原处。
规则:只有拿到两只筷子时,哲学家才能吃饭;只有拿到两只筷子时,哲学家才能吃饭;如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;任何一个哲学家在自己没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。
为了解决哲学家就餐问题同时解决死锁现象,需要设计一定的解决策略。
有这样几种解决办法:1.至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐;2.仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐;3.规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。
该实验我采取了第2种解决方案,每个哲学家在确定自己左右两边的筷子都能用时,才能同时拿起两只筷子进餐,进餐完成后同时放下两只筷子。
三、数据结构、功能设计(功能与框图、功能模块说明)该实验使用java的多线程,同时利用到关键字synchronized实现了共享数据的互斥锁定,以保证每只筷子的状态的互斥的。
哲学家进餐问题及解决方案.pdf
哲学家进餐问题及解决方案北京交通大学计算机学院翟高寿哲学家进餐问题描述❑哲学家进餐问题是典型的同步问题五个哲学家共用一张圆桌,分别坐在环桌均匀摆放的五张椅子上,并全部实践着交替地进行思考和进餐的生活方式圆桌上放有五支筷子,均匀排放在哲学家之间的位置上哲学家饥饿时便试图去取用圆桌上最靠近他左右两端的两支筷子,且只有在同时拿到两支筷子时方可进餐,进餐完毕则把筷子放回原处,并继续进行思考哲学家进餐问题解析(待续) ❑筷子是临界资源信号量数组chopstick[0..4],初始值均为1❑第i个哲学家活动Think;wait(chopstick[i]);wait(chopstick[(i+1)mod 5]);Eat;signal(chopstick[i]);signal(chopstick[(i+1)mod 5]);321 44321哲学家进餐问题解析(续)❑上述解决方案在五个哲学家同时饥饿且各自拿起左边筷子的情况下会引起死锁❑避免死锁的三种方法①仅当哲学家左右两支筷子均可使用时,才允许他拿筷进餐②奇数号哲学家先拿左筷后拿右筷;而偶数号哲学家则相反③至多允许四个哲学家同时进餐,以保证至少有一个哲学家可以同时拿到两支筷子而进餐3 21 44321哲学家进餐主程序设计①双筷齐举[AND型信号量] Varchopstick: array[0..4] of semphore (1,1,1,1,1); beginparbeginphilosophy0 ;… ; philosophy i; …philosophy4;parendend哲学家进餐子程序设计①双筷齐举[AND型信号量] philosophy i :beginrepeatThink;Swait(chopstick[i], chopstick[(i+1)mod 5]); Eat;Ssignal(chopstick[i], chopstick[(i+1)mod 5]); until false;end哲学家进餐主程序设计①双筷齐举[记录型信号量] Varchopstick: array[0..4] of semphore:=(1,1,1,1,1); mutex: semphore:=1;beginparbeginphilosophy0 ;… ; philosophy i; …philosophy4;parendend哲学家进餐子程序设计①双筷齐举[记录型信号量] philosophy i :beginrepeatThink;wait(mutex);wait(chopstick[i]);wait(chopstick[(i+1)mod 5]);signal(mutex);Eat;signal(chopstick[i]);signal(chopstick[(i+1)mod 5]);until false;end哲学家进餐主程序设计②奇偶有别[记录型信号量] Varchopstick: array[0..4] of semphore (1,1,1,1,1); beginparbeginphilosophy0 ;… ; philosophy i; …philosophy4;parendend哲学家进餐子程序设计②奇偶有别[记录型信号量] philosophy i (i为奇数,即奇数号哲学家):beginrepeatThink;wait(chopstick[i]);wait(chopstick[(i+1)mod 5]);Eat;signal(chopstick[i]);signal(chopstick[(i+1)mod 5]);until false;end哲学家进餐子程序设计②奇偶有别[记录型信号量] philosophy i (i为偶数,即偶数号哲学家):beginrepeatThink;wait(chopstick[(i+1)mod 5]);wait(chopstick[i]);Eat;signal(chopstick[(i+1)mod 5]);signal(chopstick[i]);until false;end哲学家进餐主程序设计③进餐限数[记录型信号量] Varchopstick: array[0..4] of semphore:=(1,1,1,1,1); limit: semphore:=4;beginparbeginphilosophy0 ;… ; philosophy i; …philosophy4;parendend哲学家进餐子程序设计③进餐限数[记录型信号量] philosophy i :beginrepeatThink;wait(limit);wait(chopstick[i]);wait(chopstick[(i+1)mod 5]);signal(limit);Eat;signal(chopstick[i]);signal(chopstick[(i+1)mod 5]);until false;end知行合一,开拓进取!哲学家进餐问题及解决方案■。
哲学家进餐问题
死锁避免算法要求哲学家在取餐时按照固定的方向(顺时针或逆时针)进行。这 样,每个哲学家都只能等待其左侧或右侧的哲学家完成进餐后才能开始进餐。通 过这种方式,可以确保不会出现循环等待的情况,从而避免死锁的发生。
算法二:资源分级算法
总结词
资源分级算法通过优先满足更高级别的资源请求,避免死锁 的发生。
它被用来探讨多线程或多进程同步时可能出现的资源竞争和死锁情况。
问题的重要性
01
哲学家进餐问题是并发计算领域中的一个经典问题 ,对理解并发控制和同步机制至关重要。
02
解决哲学家进餐问题有助于避免死锁和资源竞争, 提高并发系统的可靠性和效率。
03
该问题还促进了并发算法和同步机制的研究,推动 了计算机科学的发展。
THANKS FOR WATCHING
感谢您的观看
哲学家进餐问题被视为并发控制领域的经典问题,它揭示了在并 发系统中资源访问冲突和死锁的可能性。
资源分配
该问题引发了对资源分配策略的深入研究,如何合理地分配资源以 避免冲突和死锁,成为计算机科学领域的重要议题。
算法设计
哲学家进餐问题为算法设计提供了一种挑战性的场景,促使研究者 设计出更高效、安全的并发算法和协议。
哲学家进餐问题
汇报人: 202X-01-05
contents
目录
• 问题的背景和起源 • 问题描述和模型建立 • 解决方案和算法 • 问题的影响和启示 • 问题的发展和未来方向
01
问题的背景和起源
问题的起源
哲学家进餐问题源于计算机科学和数学的交叉领域,特别是并发计算和同步问题。
该问题由艾兹赫尔·戴克斯特拉在1965年首次提出,旨在解决并发控制中的死锁问题 。
哲学家就餐问题的算法实现
哲学家就餐问题的算法实现在哲学家就餐问题中,假定有五位哲学家围坐在一张圆桌旁,每位哲学家面前都放着一碗意面和一把叉子。
这五位哲学家中的每位都有两种活动,一种是思考,一种是就餐。
但是,这五位哲学家只有五支叉子共用,也就是说,每个哲学家只能在自己左右两边分别拿起一把叉子。
若这五位哲学家中有若干人同时拿着左手边的叉子,或者同时拿着右手边的叉子,那么他们都无法就餐。
这时,就需要找到一种算法来解决这个问题。
解法一:Chandy/Misra解法Chandy/Misra解法是一种分布式算法,它的思路是使得每一位哲学家都向右边的人要叉子。
一旦它们都拿到了右边的叉子,就会开始就餐,然后把左右两个叉子都放回去。
这种算法的优点是它具有分布式系统的特点,不会造成资源竞争,而且在算法处理结束后,所有人都不会处于饥饿状态。
但是,这种算法实现的难度比较大,因为需要每个哲学家都向右边的人要叉子,而且需要考虑异常情况。
解法二:Dijkstra解法Dijkstra解法也被称为银行家算法,它的思路是让每一位哲学家先拿一支叉子,只有拿到两支叉子后,才可以开始就餐。
一旦就餐结束,哲学家就将叉子放回去。
这种算法的优点是它比较简单,易于实现。
但是,如果有一位哲学家先拿了一支叉子并且不再释放,那么其他哲学家就会陷入死锁状态。
解法三:Semaphore解法Semaphore解法是以信号量为基础的算法,它的思路是对每支叉子定义一个信号量,并使用信号量来控制哲学家与叉子之间的关系。
一旦一个哲学家想要就餐,就需要请求两个叉子的信号量,如果请求不到,则会被阻塞。
这种算法的优点是它具有可扩展性,而且可以支持多个进程同时使用资源。
但是,它比较复杂,可能会导致死锁。
结论在实际开发中,我们可以根据自己的需求选择合适的算法来解决哲学家就餐问题。
如果要求系统具有分布式系统的特点,可以使用Chandy/Misra解法;如果要求简单易行和易于实现,可以使用Dijkstra解法;如果要求可扩展性和支持多进程,可以选择Semaphore解法。
操作系统课程设计哲学家进餐问题报告
操作系统课程设计哲学家进餐问题报告课程设计报告(本科/专科)课程: 学号: 姓名: 班级: 教师: 时间:计算机科学与技术系操作系统课程设计2012.12. 7 -2013.1. 7设计名称:哲学家进餐问题设计内容、目的与要求:实验目的:通过实现哲学家进餐问题的同步深入了解和掌握进程同步和互斥的原理。
内容和要求:哲学家有N个,也定全体到达后开始讨论:在讨论的间除哲学家进餐,每人进餐时都需使用刀、叉各一把,所有哲学家刀和叉都拿到后才能进餐。
哲学家的人数、餐桌上的布置自行设定,实现刀和叉的互斥使用算法的程序实现。
计划与进度安排:设计过程、步骤(可加页):3.模块分析。
(1)主程序模块:昱(2)状态改变模块:(3)返回哲学家状态模块:等待状态的转换,餐具能够实现互斥。
设计体会与建议:经过了前后共2周的时间,我完成了这次课程设计。
通过这次课程设计,我学到了许多课本上学不到的知识,注意到了许多课本上没有提到的东西。
源程序代码#include <wlndows.h>#inclucle <string> #include <lostream> #include <assert.h> using namespace std; bool tools⑹;〃全局变量,用餐工具当一个线程执CRITICAL-SECTION cs; //>号量,在线程中使用,临界区,行了EnterCritialSection之后,cs里面的信息便被修改了,以指明哪一个线程占用了它。
class Philosopher{private:int number;Hit status; /*标记当前哲学家的状态,0表示正在等待(即处于饥饿状态),1表示得到两支筷子正在吃饭,2表示正在思考public:Philosopher(lnt num=0): status(2)9 number(num) { }int find() const { return number; }int getinfo() const { return status;}void Change(); 〃状态改变函数void Philosopher::Change(){EnterCriticalSection (&cs); 〃进入临界区if(statiis==l) 〃正在进餐{tools[number%6]=true; 〃放下左手工具tools[(number-l)%6]=true; 〃放下右手工具status=2; 〃改变状态为思考if(tools[niimber%6]&&tools[(number-1) % 6]) 〃左右手两边工具均为 空闲状态{tools[number%6]=false; 〃拿起左手工具 tools[(number-l)%6]=false; 〃拿起右手工具 status=l;LeaveCriticalSection (&cs);string print(Philosopher *pA){//pA->Change();int i=pA->getinfo();string str;if(i==O)St!•■等待";else lf(i==l)sW 就餐冷else if(status=2) status=O; else lf(status=O)〃思考中〃改变状态为等待else str=ft思考";return str;}string toolstatus(bool a){string state;if(a==true)state=n闲”;if(a==false)state=M用”;return state;}int main(){char con = *y'; 〃判断是否继续for(int i=0;i<6;i++)tools[i]=true; 〃3组刀叉都未使用,初始化Philosopher P1(1),P2(2),P3(3),P4(4),P5(5),P6(6);InitializeCriticalSection (&cs); 〃初始化初始化临界区cout«f,------------------ 状态说明示意图:------- cout«tf“vv"哲学家0号的状态”vv" cout«tf哲学家5号的状态“v V" "vv"叉3的状态”vv“f,«endl;t,«endl;y刀1“VV"哲学家1号的状态n«endl;cout«fln«H X i 的状态n«endl;cout«n<学家4号的状态”vv”"vv"叉2的状态"vv”tf«H刀2的状态”vv”“VB哲学家2号的状态tf«en(ll;cout«H"vv”哲学家 3 号的状态"vv”u«endl;coutvv"餐具的状态,用表示使用中,闲表示空闲中。
哲学家就餐问题报告
哲学家就餐问题报告一、实验目的1、熟练使用VC6、0编译环境,调试并正确运行程序。
2、理解哲学家就餐问题中出现的问题,进而掌握死锁的必要条件。
3、理解源程序中产生和防止死锁的算法,及相关窗口操作。
4、熟悉哲学家就餐问题流程并写出其伪代码二、实验内容有五个哲学家围坐在一圆桌旁(如图1),桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子。
每个哲学家的行为是思考,感到饥饿,然后吃通心粉。
为了吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。
图1 图2三、实验要求1、程序需有防止死锁发生采取的措施;2、程序要有产生死锁的分配方式;四、实验算法实现1、不发生死锁的方式由源码gChopstickState[iLeftChopstick] = iPhilosopher; gChopstickState[iRightChopstick] = iPhilosopher;知基本思路是要么一下子占用两支筷子要么不占用,先确定两只筷子均没被占用才获取筷子,这样就打破了死锁的必要条件。
伪代码如下; var mutexleftchopstick,mutexrightchopstick; beging: resting; waiting; p(mutexleftchopstick); //先改变左手筷子信号量 p(mutexrightchopstick); //马上改变右手筷子信号量GetResource(leftchopstick,rightchopstick); //同时占用左右手筷子 eating; v(mutexleftchopstick); //释放资源v(mutexrightchopstick); end2、发生死锁的方式基本思路是有筷子即占用,看似效率很高,但因为资源有限,且不可抢占,很容易发生死锁。
源码理解: gDinerState[iPhilosopher] = WAITING;//wants chopsticks result = WaitForSingleObject(gchopStick[iLeftChopstick], INFINITE); gChopstickState[iLeftChopstick] = iPhilosopher; //得到左手筷子 Sleep(P_DELAY/4); //休眠状态gDinerState[iPhilosopher] = WAITING; //继续等待另一只手筷子 result =WaitForSingleObject(gchopStick[iRightChopstick], INFINITE); gChopstickState[iRightChopstick] = iPhilosopher; //直到等到右手筷子伪码书写:var mutexleftchopstick,mutexrightchopstick; beging: resting; waiting; p(mutexleftchopstick); //改变左手筷子信号量GetResource(leftchopstick); //获取左手筷子p(mutexrightchopstick); //改变右手筷子信号量GetResource(rightchopstick); //获取右手筷子 eating;v(mutexleftchopstick); v(mutexrightchopstick); end五、实验运行结果程序界面说明:通过位图句柄画演示的界面1.先画桌子,再画筷子,再画盘子,2.再画哲学家:哲学家用圆表示,根据哲学家的状态选择画笔(为resting 状态时为绿色圆圈,为等待或者,就餐时为红色圆圈)3.最后画哲学家的手:判断的依据是若筷子的编号和哲学家的编号一直致,那么认为这根筷子属于这个哲学家(筷子资源空闲)那么可以画手表示哲学家获得了这个筷子。
哲学家就餐问题
03
问题的基本描述
描述问题的具体内容
哲学家就餐问题的背景
问题的具体描述:哲学家就餐问题的描述和场景
问题的解决思路:如何解决哲学家就餐问题
问题的启示:哲学家就餐问题对人工智能和计算机科学的影响和启示
解释问题中的关键概念
哲学家就餐问题:描述了哲学家在吃饭时如何避免死锁的问题
意义:哲学家就餐问题不仅是一个理论问题,更是一个具有现实意义的问题。通过研究和探讨这个问题,我们可以更好地理解现实生活中的资源分配和优先级排序等问题,并找到更好的解决方案。
07
总结与展望
总结哲学家就餐问题的核心内容和解决方案
核心内容:哲学家就餐问题的本质是死锁问题,涉及到多个哲学家同时竞争有限的资源,导致系统无法继续运行。
哲学家就餐问题的应用:如“哲学家就餐问题在计算机科学中的应用”、“哲学家就餐问题在人工智能领域的应用”等。
哲学家就餐问题的启示:如“哲学家就餐问题对计算机科学的启示”、“哲学家就餐问题对人工智能的启示”等。
探讨如何深化对哲学家就餐问题的理解
了解问题的背景和起源
探讨问题在现实生活中的应用和意义
思考问题对未来发展的影响和价值
添加标题
添加标题
添加标题
添加标题
哲学家就餐问题解决方案:优点是解决了死锁问题,缺点是实现较为复杂。
0-1筷子解决方案:优点是简单直观,缺点是可能导致死锁。
信号量解决方案:优点是避免了死锁,缺点是实现较为复杂。
管程解决方案:优点是简单直观,缺点是可能导致死锁。
探讨解决方案的实际应用
解决方案的扩展应用:多线程同步问题
问题的起源:起源于古希腊哲学家苏格拉底的故事
哲学家就餐问题解决方案
哲学家就餐问题解决方案
1. 哎呀呀,哲学家就餐问题啊!咱可以试试这样,就像拼图一样,把各种口味、各种菜品都摆在一起,看看能不能拼成一个完美的“美食地图”。
比如柏拉图喜欢思考,那就给他来一份精致的沙拉,边吃边想呗。
2. 嘿,为什么不搞个主题餐厅呢?像开个“哲学沙龙餐厅”,大家边吃边探讨深奥的问题呀。
就好像孔子和他的弟子们围坐一起讲学吃饭那样,多有意思!苏格拉底肯定超爱这种氛围。
3. 要不,给哲学家们来个定制菜单吧!根据他们的哲学理念来配餐,这不是超酷吗?老子主张自然无为,那就给他上些清淡自然的食物。
这就好像为他们量身打造的衣服一样合适。
4. 哎呀,我们可以搞些哲学趣味餐具呀!比如餐盘上印着各种哲学名言,吃着吃着还能激发灵感呢。
这不就跟阿基米德在浴缸里发现浮力原理似的嘛!
5. 或者,举办哲学美食节怎么样?把哲学家们喜欢的食物都集中起来,那场面,肯定火爆。
这就如同一场哲学的盛宴,亚里士多德肯定会成为其中最闪亮的嘉宾。
6. 让服务员也都变成哲学小达人呀,能和哲学家们聊聊哲学顺便推荐菜品。
就像伯牙子期遇到懂他音乐的人一样,多棒!尼采遇到这样的服务员想必也会很开心。
7. 可以建个哲学美食交流群呀,大家在里面分享好吃的和哲学见解。
这不就相当于给哲学家们搭了个专属的交流平台嘛,毕达哥拉斯肯定会积极发言的。
8. 干脆来个哲学厨艺大比拼吧,让哲学家们也参与进来。
这多好玩呀,就好像他们在哲学战场上辩论一样激烈。
我觉得要解决哲学家就餐问题,就得有创意又有趣,让他们在享受美食的同时也能沉浸在哲学的氛围里。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统
实验报告
实验名称:哲学家就餐问题
班级:信卓1201班
姓名:钟远维
学号:U201213500
日期:2014年10月30日
一、实验目的
1、熟练使用VC6.0编译环境,调试并正确运行程序。
2、理解哲学家就餐问题中出现的问题,进而掌握死锁的必要条件。
3、理解源程序中产生和防止死锁的算法,及相关窗口操作。
4、熟悉哲学家就餐问题流程并写出其伪代码
二、实验内容
有五个哲学家围坐在一圆桌旁(如图1),桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子。
每个哲学家的行为是思考,感到饥饿,然后吃通心粉。
为了吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。
图1 图2
三、实验要求
1、程序需有防止死锁发生采取的措施;
2、程序要有产生死锁的分配方式;
四、实验算法实现
1、不发生死锁的方式
由源码gChopstickState[iLeftChopstick] = iPhilosopher;
gChopstickState[iRightChopstick] = iPhilosopher;
知基本思路是要么一下子占用两支筷子要么不占用,先确定两只筷子均没被占用才获取筷子,这样就打破了死锁的必要条件。
伪代码如下;
var mutexleftchopstick,mutexrightchopstick;
beging:
resting;
waiting;
p(mutexleftchopstick); //先改变左手筷子信号量
p(mutexrightchopstick); //马上改变右手筷子信号量
GetResource(leftchopstick,rightchopstick); //同时占用左右手筷子
eating;
v(mutexleftchopstick); //释放资源
v(mutexrightchopstick);
end
2、发生死锁的方式
基本思路是有筷子即占用,看似效率很高,但因为资源有限,且不可抢占,很容易发生死锁。
源码理解:
gDinerState[iPhilosopher] = WAITING; //wants chopsticks
result = WaitForSingleObject(gchopStick[iLeftChopstick], INFINITE);
gChopstickState[iLeftChopstick] = iPhilosopher; //得到左手筷子
Sleep(P_DELAY/4); //休眠状态
gDinerState[iPhilosopher] = WAITING; //继续等待另一只手筷子
result = WaitForSingleObject(gchopStick[iRightChopstick], INFINITE);
gChopstickState[iRightChopstick] = iPhilosopher; //直到等到右手筷子
伪码书写:
var mutexleftchopstick,mutexrightchopstick;
beging:
resting;
waiting;
p(mutexleftchopstick); //改变左手筷子信号量
GetResource(leftchopstick); //获取左手筷子
p(mutexrightchopstick); //改变右手筷子信号量
GetResource(rightchopstick); //获取右手筷子
eating;
v(mutexleftchopstick);
v(mutexrightchopstick);
end
五、实验运行结果
程序界面说明:
通过位图句柄画演示的界面
1.先画桌子,再画筷子,再画盘子,
2.再画哲学家:
哲学家用圆表示,根据哲学家的状态选择画笔(为resting 状态时为绿色圆圈,为等待或者,就餐时为红色圆圈)
3.最后画哲学家的手:
判断的依据是若筷子的编号和哲学家的编号一直致,那么认为这根筷子属于这个哲学家(筷子资源空闲)那么可以画手表示哲学家获得了这个筷子。
(获得资源)
六、实验总结
通过本次实验,程序设计的时候应该有适当的避免死锁的产生的算法程序。
当避免死锁产生算法不完美时,有锁死产生的时候的死锁分配方式。
这些都是在程序设计的时候应该先想好的。
通过实践总结,有以下三种方法可以避免一类死锁。
一是至多允许4位哲学家同时吃通心面;二是奇数号哲学家先取左边叉子,再取右边叉子;偶数号哲学家先取右边叉子,再取左边叉子;三是每位哲学家取到手边的两把叉子才开始吃通心面,否则一把叉子也不取。
本次实验在已给源码的基础上我们主要是理解C语言程序并提高伪代码书写能力;所以第一步是要弄懂这个哲学家就餐问题的算法思路,然后结合课堂上老师对伪代码算法的讲解,我们将思路用伪码总结出来。
从这次实验中,我们的另一个收获是对同一个问题的多方向思考。
从代码中可以看出不同的分配方式,有的会避免产生死锁,有的可能会导致死锁的发生且时间长短不一样。
这不禁让我们思考多种解决死锁的方案,但每种方案从时间、代码量等方面考虑各有优缺点,要想得到最佳的解决方法就需要我们在以后的实践中去不断探索。