哲学家进餐问题(操作系统)
操作系统实验报告(哲学家问题)
操作系统实验报告实验者:朱毅学号:0701013 实验题目:哲学家问题设有5个哲学家,共享一张放有5把椅子的桌子,每人分得一把椅子。
但是,桌子上总共只有5支筷子,在每人两边分开各放一支。
哲学家们在肚子饥饿时才试图分两次从两边拾起筷子就餐。
条件:(1)只有拿到两支筷子时,哲学家才能吃饭。
(2)如果筷子已在他人手上,则哲学家必须等他人吃完之后才能拿到筷子。
(3)任一哲学家在自己未拿到两支筷子吃饭之前,决不放下自己手中的筷子。
试:(1)描述一个保证不会出现两个邻座同时要求吃饭的通信算法。
(2)描述一个既没有两邻座同时吃饭,又没有人饿死(永远拿不到筷子)的算法。
(3)在什么情况下,5个哲学家全部吃不上饭?开发环境:Microsoft V isual Foxpro 6.0算法描述:数据环境:表KUAIZI 相应字段:筷子号状态(逻辑型)使用者桌号表ZHEXUEJIA相应字段:哲学家名所属状态拥有左筷子(逻辑型)拥有右筷子(逻辑型)桌号表FANGAN 相应字段方案表的具体内容请参见DAIMA.DOC文件本程序解决死锁的关键:从苏格拉底开始往黑格尔依次处理,对每人的处理一次进行到底,从而肯定必然有一人完全占有资源,避免了死锁,其实质就是按照5个哲学家的座位号作为绝对的优先级进行资源的先后分配。
初始状态:选择算法(以下两算法不同之处用黑体标识)算法一:(1)保证不会出现两个邻座同时要求吃饭的通信算法。
1、由操作人员按“有人饿了”按钮,控制是否有哲学家肚子饿了。
2、出现复选框和“确定”按钮,挑选哲学家后,按“确定”后确认选择。
当做出一个选择后,该哲学家左右两边的哲学家则不能被选中(通过对复选框的ENABLED属性控制),若取消选中,则该哲学家左右两边的哲学家(在该哲学家的另一邻居也未被选中为前提) 还原为可选状态。
3、“确认”后执行以下步骤:①从苏格拉底到黑格尔依次检验其是否是此次被选中②若是此次被选中,进行以下步骤:a 改变表KUAIZI 和表ZHEXUEJIA中相应的字段:ZHEXUEJIA:所属状态由F(Full)改为H(Hungry)b执行PROG1,分配给这些饥饿的哲学家筷子,若左边有筷子,取之,并标识“拥有左筷子”;若右边有筷子,取之,并标识“拥有右筷子”。
操作系统课程设计——哲学家进餐问题
操作系统课程设计——哲学家进餐问题1000字哲学家进餐问题是一个经典的多线程同步问题,在操作系统中有着广泛的应用。
因此,在操作系统课程设计中,探究哲学家进餐问题是一件非常有意义的事情。
哲学家进餐问题的场景是:五个哲学家围坐在一张圆桌前,每个哲学家的左右两侧有一只筷子,他们需要利用这两只筷子才能进餐。
每个哲学家有两种状态:思考和进餐。
当一个哲学家处于进餐状态时,他需要同时获取他左右两侧的筷子,进餐结束后,他会释放这两只筷子,进入思考状态。
在这个场景中,如果所有的哲学家都同时想要进餐,那么就可能会出现死锁情况,即所有的哲学家都拿到了左手边的筷子,但都无法拿到右手边的筷子,导致无法进餐。
因此,需要在代码中实现同步互斥机制,避免死锁的发生。
本课程设计中,我使用了Java语言来实现哲学家进餐问题。
在代码实现中,首先定义了哲学家、筷子、餐桌等对象,然后使用线程来模拟哲学家的思考和进餐过程。
为了避免死锁,我使用了Chandy/Misra算法,即每个哲学家先尝试去取左手边的筷子,如果取不到就不再继续等待,而是重新回到思考状态,等待下一个机会。
同时,当一个哲学家取到了左手边的筷子之后,如果发现右手边的筷子已被占用,他就会释放左手边的筷子,重新回到思考状态,等待下一个机会。
在实现过程中,我还使用了信号量机制,保证了线程间的同步互斥。
每个筷子都是一个二元信号量,初始为1,表示可用。
当一个哲学家拿起筷子时,他会将对应的信号量减1,表示不可用。
当哲学家用完筷子之后,会将对应的信号量加1,表示可用。
通过这种方式,实现了对筷子的访问同步。
最后,我对代码进行了测试,模拟了多位哲学家同时进行进餐的过程。
在测试中,我发现哲学家进餐的速度受到筷子的数量和哲学家思考进餐比例的影响。
当筷子数量少于哲学家数量时,容易出现死锁;当哲学家思考和进餐的时间相当时,程序的运行情况比较稳定。
总的来说,本课程设计实现了哲学家进餐问题,通过学习该问题,我更深入地理解了同步互斥机制的重要性,并学会了如何使用信号量来实现同步互斥。
哲学家进餐问题(操作系统)
哲学家进餐问题(操作系统)哲学家进餐问题(操作系统)1. 引言文档概述:在操作系统领域,哲学家进餐问题是一个经典的并发控制问题。
该问题模拟了五位哲学家围坐在一张圆桌旁,每个哲学家面前放置着一碗面和一只叉子。
哲学家在思考和进餐之间切换,但是他们必须分享叉子来进行进餐。
然而,如果每个哲学家都同时拿起右边的叉子,就会出现死锁的情况。
因此,设计一个合理的算法来解决这个问题是非常重要的。
2. 问题描述2.1 哲学家和叉子在该问题中,有五位哲学家分别编号为 P1、P2、P3、P4、P5,以及五只叉子,编号为 F1、F2、F3、F4、F5.每个哲学家在思考时不会使用叉子,而在进餐时需要使用相邻两只叉子。
2.2 运行过程哲学家的运行过程根据以下步骤进行:- 当一个哲学家饿了后,他会尝试获取左边和右边的叉子。
- 如果两只叉子都可用,哲学家就会进餐,并在完成后释放叉子。
- 否则,哲学家需要等待其他哲学家释放叉子。
3. 解决方案为了解决哲学家进餐问题,我们可以采用以下方法之一:3.1 资源分级分配算法该算法将叉子分为左叉子和右叉子,每个哲学家只能同时拿起左叉子和右叉子。
通过约定哲学家只能按照一定顺序拿起叉子,可以避免死锁的发生。
3.2 资源分级分配算法的伪代码:```acquire_forks(left_fork_id, right_fork_id) {if (left_fork_id < right_fork_id) {acquire(left_fork_id);acquire(right_fork_id);} else {acquire(right_fork_id);acquire(left_fork_id);}}release_forks(left_fork_id, right_fork_id) { release(left_fork_id);release(right_fork_id);}philosopher(id) {while (true) {think();acquire_forks(id, (id + 1) % 5);eat();release_forks(id, (id + 1) % 5);}}```4. 附件本文档不涉及附件。
哲学家吃饭问题试验报告操作系统
目录1.设计题目与要求21.1设计目的1.2设计要求2.总体设计思想与相关知识22.1总体设计思想2.2问题描述2.3解决方案3.数据结构、流程图23.1数据结构3.2流程图4.源代码.35.运行结果.66.结果分析.77.总结及心得体会.71.设计题目与要求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为了防止死锁,把哲学家分为三种状态,思考,饥饿,进食,仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子,并且一次拿到两只筷子,否那么不拿.3.数据结构及流程图3.1数〞结构philosopherProc+myid:int+mystate:int+philosopherProc(LPVOIDlpParameter)+ResumeThread(hPhilosopher[i]):int +strcpy(stateStr, ""):int程序中定义一个哲学家类,包含两个私有对象和四个公有对象.myid对象:报讯哲学家的编号.mystate对象:用于保存当前该哲学家的状态,philosopherProc( LPVOID lpParameter) 方法:哲学家类构造函数,PHILOSOPHER_NUM表示哲学家编号ResumeThread(hPhilosopher[i]) 方法:返回该哲学家编号strcpy(stateStr,"") 方法:返回哲学家当前状态根据题目要求改变哲学家的状态(饥饿 ,进餐,思考,饥饿)3.2流程图的一个概念.指的是一个核心对象在某一个进程中的唯一索引*/HANDLE semaphore[PHILOSOPHER_NUM]; // semaphore 用来表示筷子是否可用4. 源代码〔c++〕//哲学家就餐问题的解法 #include <windows.h> #include <process.h> #include <time.h> #include <stdlib.h> #include <stdio.h> #include <iostream> using namespace std;有效//命名空间std 内定义的所有标识符都 const unsigned int PHILOSOPHER_NUM=5; //const char THINKING=1;表示得到饥饿,3表示正在吃饭*/ const char HUNGRY=2; const char DINING=3; HANDLE hPhilosopher[5];/*///*HANDLE 〔 哲学家数目标记当前哲学家的状态,1表示等待,2定义数组存放哲学家句柄〕是windows 操作系统中DWORD WINAPI philosopherProc( LPVOID IpParameter) // 据)的API函数philosopherProc {int myid;char 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);cout << "philosopher " << myid << " begin" << endl;ReleaseMutex(mutex);mystate = THINKING;//THINKINGHANDLE mutex;// Mutex 用来限制平安输出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 == WAIT_OBJECT_0){ret = WaitForSingleObject(semaphore[rightFork], 0); // 再检查右筷子是否可用if (ret == WAIT_OBJECT_0){mystate = DINING;//变自己的状态strcpy(stateStr, "DINING");)else{ReleaseSemaphore(semaphore[leftFork], 1, NULL); // 用,就把左筷子放下改变状态先检查左筷子是否左筷子可用就拿起,右筷子可用,就改如果右筷子不可返回DWORD32位数初始状态为)break;case DINING://吃完后把两支筷子都放下ReleaseSemaphore(semaphore[leftFork], 1, NULL);ReleaseSemaphore(semaphore[rightFork], 1, NULL);mystate = THINKING;//改变自己的状态strcpy(stateStr, "THINKING");break;)// 输出状态WaitForSingleObject(mutex, INFINITE);cout << "philosopher " << myid << " is : " << stateStr << endl;ReleaseMutex(mutex);// sleep a random time : between 1 - 5 sint sleepTime;sleepTime = 1 + (int)(5.0*rand()/(RAND_MAX+1.0));Sleep(sleepTime*10);))int main(){int i;srand(time(0));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);)for (i=0; i<PHILOSOPHER_NUM; i++)ResumeThread(hPhilosopher[i]);Sleep(2000);return 0;)5.运行结果6.结果分析对哲学家进行编号,将他们的初始状态全部设定为THINGKING接着先从0开始改变他们的状态为HUNGRY继续运行后4号和2号哲学家先DINING, 3号和1号哲学家为HUNGRY当4号哲学家吃完后,0号哲学家就开始DINING7.总结及心得体会这次操作系统的作业让我深刻的体会到操作系统的知识作用.培养我综合运用知识的水平,结合了C++的知识来解决这个问题.稳固了以前的知识.在设计这个程序的时候我遇到了很多困难,但是通过老师和同学们的帮助,我一一解决掉了.而且发现了我很多学习中的缺乏之处,对以前学习的知识熟悉不够深刻,掌握的不够,这个要好好复习一下.总的来说,这个操作系统的作业带给我很多收获,让我受益匪浅.封pliilcsopher.cpp附件:。
操作系统课程设计哲学家就餐问题
目录摘要 (2)第一章课程设计的目的及要求 (3)1.1设计目的 (3)1.2设计要求 (3)1.3设计环境 (3)第二章需求分析 (4)2.1问题描述: (4)2.2问题分析: (4)第三章详细分析 (5)3.1 问题定义 (5)3.2算法分析: (5)3.3 界面设计 (6)第四章程序部分代码分析 (8)第五章新得体会 (10)第六章参考文献 (11)附录 (11)摘要在多道程序环境下,进程同步问题十分重要,也是相当有趣的问题,因而吸引了不少学者对它进行研究,由此而产生一系列经典的进程同步问题.其中较有代表性的是哲学家进餐问题等等,通过这些问题的研究和学习,可以帮助我们列好地理解进程同步概念及实现方法.由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题,该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和进餐,平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐,进餐毕,放下筷子继续思考.由于筷子数目有限,不能让五个哲学家同时进餐,而且甚至只能让其中的少数哲学家进餐,其他的哲学家只能轮流享用,这非常类似多线程之间的同步互斥问题,所以采用windows的多线程及一些API函数实现了对这个经典算法的模拟.第一章课程设计的目的及要求1.1设计目的通过本次课设,对本学期的操作系统课程的学习理论知识的一次应用。
是理论结合实际的一次应用。
让我们学会对竞争资源的操作,控制,同时锻炼我们的编程水平。
使我们掌握多线程编程的方法;掌握MFC程序设计和API应用程序编程;培养我们基本控制程序的安全性及避免死锁的方法;培养我们分析、解决问题的能力;锻炼我们的自学能力;培养我们的组队合作能力;提高学生的科技论文写作能力。
1.2设计要求✧利用多线程编程模拟5个线程,竞争五个筷子去吃通心面;✧对临界资源的操作算法要简单易行;✧程序运行时不会产生死锁;✧对所设计的各模块系统进行调试;✧独立完成程序的设计与调试;✧设计好各个功能模块,合理安排他们的位置;✧程序结构清晰;✧程序界面友好直观。
计算机操作系统哲学家进餐问题的教学探讨
计算机操作系统哲学家进餐问题的教学探讨
计算机操作系统哲学家进餐问题是一个经典的模拟问题,用于帮助学生理解线程同步、死锁和资源管理等操作系统的核心概念。
该问题描述了n个哲学家围坐在一张圆桌周围,每个哲学家面前有一盘食物,中间有n个筷子。
哲学家需要吃饭,但是每个哲学家只能使用自己左右两边的筷子来进餐。
如果哲学家发现左边或右边的筷子被占用,就会等待,直到筷子被释放。
这个问题中存在死锁的可能性。
在教学中,可以通过演示代码或编写代码来模拟这个问题的运行情况,帮助学生理解这些概念的实际应用。
例如,可以演示如何使用锁和条件变量来解决死锁问题,或者如何
使用信号量管理系统资源来避免死锁问题。
另外可以讨论不同的算法和策略,如顺序获取筷子,随机获取筷子等,来说明如何避免死锁的发生.
总之,通过这个问题的模拟,学生可以加深对操作系统的理解,并且对如何解决多线程并发问题有更深入的了解。
在教学探讨中,老师可以通过不同的模拟实验来说明线程同步和死锁的本质原理以及如何避免和解决这些问题。
鼓励学生进行自己的实验和探究,以加深对这些概念的理解。
哲学家就餐-操作系统
衡阳师范学院操作系统课程设计报告题目哲学家就餐问题学生姓名文润学号 ******** 专业班级计算机科学与技术1402班指导教师王玉奇完成时间 2016.11.29目录一、设计要求 (2)实验目的: (2)设计要求: (2)二、运行环境 (2)三、设计思想及流程 (2)设计思想: (2)流程图: (4)主要数据结构: (5)四、运行结果 (5)五、设计心得 (6)六、参考资料 (6)七、程序清单 (7)一、设计要求1.实验目的:通过实现哲学家就餐问题的互步,深入了解和掌握进程互斥的原理。
2.设计要求:哲学家有N个,规定全体到齐后开始讨论,在讨论的间隙哲学家就餐,每人进餐时都需使用刀、叉合一把,所有哲学家刀和叉都拿到后猜能进餐。
哲学家的人数、餐桌上的布置自行设定,实现刀和叉的互斥使用算法的程序实现。
二、运行环境操作系统:Windows系统编程语言:Java语言编译软件:Eclipse三、设计思想及流程1.设计思想:对问题分析可知,目前问题的瓶颈在于:死锁。
死锁的发生必须满足以下四个必要条件:①互斥:至少有一个资源每次只能被一个进程使用,即非共享模式。
这里指每只刀叉只能被一个哲学家持有。
②占有并等待。
一个进程因请求资源而阻塞时,对已获得的资源保持不放。
③不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
这里指哲学家不能去抢别人的刀叉。
④循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
在系统设计、进程调度等方面注意避免让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。
此外,也要防止进程在处于等待状态的情况下占用资源。
经分析可知,放在桌子上的刀叉是临界资源,在一段时间内只允许一位哲学家使用,为了实现对刀叉的互斥使用,可以用一个信号量表示一只刀叉,由这N 个信号量组成信号量数组。
操作系统哲学家就餐问题实验报告
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;}。
操作系统哲学家就餐问题课程设计c语言
1.1 设计题目描述:
用多线程同步方法解决哲学家就餐问题(Dining-Philosophers Problem)
1.2 要求:
1)为每个哲学家产生一个线程,设计正确的同步算法 2)每个哲学家取得一双筷子开始用餐后,即时显示“Dining…”和该哲学 家的自定义标识符以及餐桌上所有几位哲学家标识符及其所坐的位置。 3)设定共有 5 个哲学家需用餐。每位用餐耗时 10 秒钟以上。 4)多个哲学家须共享操作函数代码。
针对每个哲学家通过共享操作函数代码分别建立5个线程以实现同步哲学家就餐而申请进入餐厅的哲学家进入room的等待队列根据fifo的原则总会进入到餐厅就餐因此不会出现饿死和死锁的现象针对5只筷子分别设置了5个互斥信号量以保证每只筷子每次只能被取得一次
武汉理工大学《操作系统》课程设计
题 目 : 用 多 线 程 同 步 方 法 解 决 哲 学 家 就 餐 问 题 (Dining-Philosophers
2. 设计说明书内容要求: Nhomakorabea1)设计题目与要求 2)总的设计思想及系统平台、语言、工具等。 3)数据结构与模块说明(功能与流程图) 4) 给出用户名、 源程序名、 目标程序名和源程序及其运行结果。 (要 注明存储各个程序及其运行结果的 Linux 主机 IP 地址和目录。 ) 5)运行结果与运行情况 (提示: (1)连续存储区可用数组实现。 (2)编译命令可用: cc (3)多线程编程方法参见附件。 )
2.2 系统平台、语言及工具
(1)操作系统:Linux (2)程序设计语言:C 语言 (3)工具:编辑工具 Vi、编译器 gcc
1
武汉理工大学《操作系统》课程设计
3.数据结构与模块说明
线程创建函数 pthread_create 声明如下: #include <pthread.h> int pthread_create (pthread_t *thread,pthread_attr_t *attr,Void* (*start_routine)(void *),void *arg);
哲学家进餐问题和银行家算法
哲学家进餐问题和银行家算法是操作系统中的经典问题,都涉及到资源分配和死锁的问题。
哲学家进餐问题是关于死锁的经典问题。
假设有五位哲学家坐在一张圆桌周围,他们轮流思考和吃饭。
吃饭的时候,他们需要使用两边的筷子。
问题是,如果哲学家们在拿起左边的筷子之前必须等待右边的筷子可用,那么有可能发生死锁。
例如,如果每个哲学家都拿起左边的筷子并等待右边的筷子,那么就会出现循环等待的情况,导致所有人都饿死,这就是死锁。
为了避免这种情况,操作系统需要一种机制来避免死锁,比如规定哲学家们必须按照固定的顺序拿起筷子等。
银行家算法是关于资源分配和避免死锁的算法。
该算法模拟了银行贷款的场景,通过检查请求是否会导致死锁来决定是否分配资源。
如果分配资源会导致死锁,算法就会拒绝该请求;否则,它就会分配资源。
银行家算法需要在操作系统中进行配置,以便动态管理资源的分配,并在需要时回收资源以避免死锁。
这两个问题的解决方法是操作系统中的重要组成部分,旨在确保系统中的多个进程或线程能够公平地共享资源,并避免出现死锁等不期望的情况。
操作系统实验报告哲学家就餐
操作系统实验报告哲学家就餐一、实验目的:通过模拟哲学家就餐问题,了解并掌握操作系统中的进程同步机制,以及解决进程间资源竞争所引发的死锁问题。
二、实验介绍:哲学家就餐问题是由荷兰计算机科学家伊克斯特拉(Dijkstra)于1965年首次提出的。
其问题描述如下:五位哲学家坐在一张圆桌子周围,每个哲学家面前有一碗饭和一根筷子。
哲学家的生活方式是交替地进行思考和进食。
当一个哲学家思考时,他不需要使用他的两个筷子;当一个哲学家想吃饭时,他需要同时获取他的左右两个筷子,并在获取到筷子后才能开始进食。
问题的关键是如何解决哲学家间的筷子竞争问题,以及避免死锁的发生。
三、实验设计:1.并发思路每个哲学家作为一个进程,在进行思考和进食这两个操作之前,需要获取他的两个筷子。
接下来考虑进程同步的两个关键点:-互斥:保证每个筷子同时只能被一个哲学家使用,避免资源竞争问题。
-死锁避免:通过限制只允许至多四位哲学家同时持有筷子,从而避免死锁发生。
2.进程同步机制- 互斥:使用Semaphore实现互斥,每个筷子都是一个Semaphore,初始值为1-死锁避免:引入一个全局计数器,记录当前持有筷子的哲学家数量,每次哲学家想要获取筷子时,先检查该计数器,仅当计数器小于4时才会获取筷子。
四、实验步骤:1.创建5个哲学家进程和5个筷子线程。
2.每个哲学家的线程循环执行思考和进食操作。
3.在进食之前,哲学家需要获取两个筷子,获取筷子的顺序按照哲学家编号进行,每个哲学家先获取自己的左边筷子,再获取自己的右边筷子。
4.进行进食操作后,哲学家释放两个筷子。
5.循环执行步骤3和步骤4,直到实验结束。
五、实验结果:通过观察实验结果,可以看到哲学家的思考和进食操作交替进行,并且避免了死锁的发生。
六、实验总结:通过本次实验,我了解了操作系统中的进程同步机制,并学会了如何解决资源竞争和死锁问题。
在本实验中,我使用了Semaphore和全局计数器实现了互斥和死锁避免,从而成功模拟了哲学家就餐问题。
操作系统课程设计哲学家进餐问题
操作系统课程设计课程设计题目:哲学家进餐问题姓名:专业:班级:学号:指引教师:6月10日目录1.设计题目与规定..........................................................................................错误!未定义书签。
1.1实验目旳..............................................................................................错误!未定义书签。
1.2初始条件..............................................................................................错误!未定义书签。
2 总体设计思想及有关知识............................................................................错误!未定义书签。
2.1总体设计思想......................................................................................错误!未定义书签。
2.2 临界区互斥编程原理.........................................................................错误!未定义书签。
2.3开发环境与工具 (3)3模块阐明 (3)3.1 状态变化模块 (4)4. 部分源程序代码及测试成果 (6)5. 课设总结.......................................................................................................错误!未定义书签。
哲学家吃饭问题 实验报告 操作系统
欢迎共阅目录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 为了避免死锁,把哲学家分为三种状态,思考,饥饿,进食,仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子,并且一次拿到两只筷子,否则不拿。
哲学家就餐问题--计算机操作系统
13、分析下面用信号量解决哲学家进餐问题的同步算法是否满足同步机制的准则。
若不满足,说明为什么,并给出满足同步机制准则的同步算法。
Var chopstick : array[0,...,4] of semaphore ;Chopstick[0]:=chopstick[1]:=chopstick[2]:=chopstick[3]:=chopstick[4]:=1;Pi: repeatwait(chopstick[i]);wait(chopstick[(i+1)mod 5]);eat ;signal(chopstick[i]);signal(chopstick[(i+1)mod 5]);think;until false;答:该算法不满足同步机制的"有限等待"原则,即每个哲学家都只拿一个筷子时就会产生死锁。
下面给出三种解决办法。
1、互斥申请资源设置信号量mutex初值为4,即最多可以有4个哲学家同时申请筷子。
这样保证了4个哲学家中至少有1人可以拿到两个筷子就餐而不发生死锁。
mutex=4Pi(i=0,1,...,4);Repeatwait(mutex);wait(chopstick[i]);wait(chopstick[(i+1) mod 5]);signal(mutex);Eat ;signal(chopstick[i]);signal(chopstick[(i+1)mod 5]);think;until false ;2、改变申请资源次序规定奇数号哲学家先拿起左边的筷子,然后再去拿右边的筷子;偶数号哲学家正好相反。
也即拿到一个筷子的哲学家才有权去拿下一个筷子,而没有拿到筷子的哲学家则退出竞争。
这样就不会出现5个哲学家都只拿一个筷子的情况。
pi(i=0,1,...4)repeatif odd(i) then /*如果i 为奇数*/beginwait(chopstick[i]);wait(chopstick[(i+1)mod 5]);endelsebeginwait(chopstick[(i+1)mod 5]);wait(chopstick[i]);endeat ;signal(chopstick[i]);signal(chopstick[(i+1)mod 5]);think;until false;3、采用AND型信号量机制AND型同步机制的思想是:将进程所需要的所有资源一次性全部分配给它,但只要有一个资源不能分配给该进程,则其它所有资源也不能分配给它。
操作系统-哲学家就餐问题
一、问题描述:有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子每个哲学家的行为是思考,感到饥饿,然后吃通心粉.为了吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子二、防止死锁发生的分配方式:仅当一个哲学家左右两边的筷子都可用时,才允许他拿筷子。
这样要么一次占有两只筷子(所有线程需要的资源)进行下一步的吃通心粉,然后释放所有的资源;要么不占用资源,这样就不可能产生死锁了。
三、产生死锁的分配方式:当筷子(资源)可用时,先分配左边的筷子,等待一会后再分配右边的筷子,由于这个过程中,左边的筷子一直没有释放,就有可能产生死锁了。
四、程序运行说明程序运行过程中会弹出一个MessageBox提示操作者操作:1.第一个对话框用于选择运行模式a.选择yes 表示采用的是运行的防止死锁的方式,这样的话整个程序可以一直运行下去,不会产生死锁。
b.选择no 表示运行产生死锁的方式会弹出第二个对话框。
2.第二个对话框用于选择运行时,线程运行的时间a. 选择 res 线程时间比较短,很快就可以死锁b.选择no 线程时间跟选择yes 时候的时间差不多,产生死锁的时间稍微长一点五、关于哲学家就餐问题的程序代码分析:A. Dining.c变量说明:函数说明:B.Mutex.c函数说明:1. DWORD WINAPI PhilosopherThread(LPVOID pVoid)哲学家进程:用于分配给哲学家筷子(资源)通过开始运行时候的对话框的选择来控制资源的分配方式:两中分配方式见二、三所述。
通过随机产生的时间来控制线程的运行,每个哲学家的状态都是resting waiting eating,一直循环。
2.int Diner(void)用于建立互斥的信号对象(筷子)和启动哲学家进程。
哲学家进餐问题(操作系统)
哲学家进餐问题(操作系统)哲学家进餐问题(操作系统)1.简介1.1 背景介绍哲学家进餐问题是计算机科学中一个经典的并发问题,最早由Edsger Dijkstra在1965年提出。
1.2 问题描述问题的场景是五位哲学家围坐在一张圆桌前,每个哲学家面前有一碗饭和一根筷子。
哲学家需要交替地思考和进餐,但是他们只能使用左右两边的筷子来进餐。
1.3 目标设计一个算法来保证哲学家们能够交替地进餐,同时避免死锁和饥饿现象的发生。
2.解决方案2.1 简单解法一个简单的解法是给每个哲学家编号,规定奇数号哲学家先拿左边的筷子,偶数号哲学家先拿右边的筷子。
当一个哲学家需要拿筷子时,他会先检查他的两边是否有其他哲学家正在使用,如果没有,他就可以拿起两边的筷子进餐。
否则,他需要等待直到两边的筷子都可用。
2.2 改进解法上述简单解法可能会导致死锁问题。
为了避免死锁,我们可以引入资源分级的概念。
每个筷子被分为两个等级,分别是主要资源和次要资源。
哲学家需要按照顺序来获取资源,例如,先获取主要资源,然后获取次要资源。
3.算法实现3.1 数据结构我们可以使用一个数组来表示圆桌上的五个筷子,同时使用一个锁数组来表示每个筷子的状态(是否被占用)。
3.2 算法流程在哲学家进餐问题中,每个哲学家都需要经历思考和进餐两个过程,我们可以使用线程来模拟这两个过程。
4.算法分析4.1 死锁问题通过引入资源分级的概念,我们成功避免了死锁问题的发生。
每个哲学家按照顺序获取资源,不会出现他们都在等待同一个资源的情况。
4.2 饥饿问题在我们的算法中,每个哲学家都会交替地进餐和思考,因此不会出现饥饿问题。
5.附件本文档暂无附件。
6.法律名词及注释6.1 死锁死锁是指在并发系统中,两个或多个进程或线程无限期地互相等待对方所占有的资源的情形。
6.2 饥饿饥饿是指某个进程或线程因无法获得所需的资源而无法继续执行的情况。
操作系统(哲学家进餐问题)
操作系统(哲学家进餐问题)哲学家进餐问题:有五个哲学家,他们的⽣活⽅式是交替地进⾏思考和进餐。
哲学家们共⽤⼀张园桌,分别坐在周围五张椅⼦上。
在圆桌上五⽀筷⼦,平时⼀个哲学家进⾏思考,饥饿时便试图取⽤其左右最靠近他的筷⼦,只有在他拿到两⽀筷⼦时才能进餐。
进程毕,放下筷⼦⼜继续思考。
问题分析:筷⼦是临界资源,⼀次只能被⼀个哲学家使⽤。
因此,五个⼈不能同时拿起左边的筷⼦(或右边)否则或引起死锁。
解决⽅案:(1)⾄多只允许四位哲学家同时拿左边的筷⼦,最终保证有⼀位哲学家能够进餐,并且⽤完能够释放筷⼦,让更多的哲学家进餐。
(2)仅当哲学家左右两只筷⼦都可以⽤的时候,才允许拿筷⼦进餐。
semaphore chopstick[5]={1,1,1,1,1};//五个信号量,⼀个信号量代表⼀只筷⼦semaphore mutex=1;Pi(){while(1){wait(mutex);//设置信号量,防⽌其它⼈争夺资源wait(chopstick[i]);wait(chopstick[(i+1)%5]);signal(mutex);//拿到两只筷⼦后释放信号量吃饭;signal(chopstick[i]);//吃过饭后,释放筷⼦资源signal(chopstick[(i+1)%5]);}}(3)奇数号哲学家先拿左边的,再拿右边的;偶数则相反。
即五位哲学家都先竞争奇数号筷⼦,获得后再去竞争偶数号筷⼦,最终总会有⼀位哲学家有两只筷⼦。
semaphore chopstick[5]={1,1,1,1,1};Pi(){while(1){if(i%2!=0){//奇数号哲学家wait(chopstick[i]);//拿左边的wait(chopstick[(i+1)%5]);//右边的}else{//偶数号哲学家wait(chopstick[(i+1)%5]);//右边的wait(chopstick[i]);//左边的}进餐;signal(chopstick[i]);//释放筷⼦资源signal(chopstick[(i+1)%5]);}}。
操作系统 哲学家进餐问题 读者—写者问题
读者—写者问题 8.3.4 读者 写者问题
有两组并发进程: 有两组并发进程 读者和写者,共享一组数据区 要求: 要求: 允许多个读者同时执行读操作 不允许读者、写者同时操作 不允许多个写者同时操作
12
读者—写者问题 8.3.4 读者 写者问题
读者--写者问题有两种类型: 读者 写者问题有两种类型: 写者问题有两种类型 第一类:读者优先- 第一类:读者优先-附解
①full:初值为 的信号量,表示缓冲区中已有的物品个数; 的信号量, :初值为0的信号量 表示缓冲区中已有的物品个数;
的信号量, ②empty:初值为 的信号量,表示缓冲区中可供使用的缓冲区数目; :初值为k的信号量 表示缓冲区中可供使用的缓冲区数目; 的信号量, ③mutex:初值为 的信号量,用于互斥使用缓冲区; :初值为1的信号量 用于互斥使用缓冲区;
Producer( ): while(TRUE) { 生产一个物品; 生产一个物品 P(empty); P(mutex);
/* 申请缓冲区里的空位 */ /* 进入临界区 */ /* 生产者进程程序 */
Consumer( ): { P(full); P(mutex);
/* 消费者进程程序 */
/* 缓冲区里有物品吗?*/ /* 进入临用数据时, 用数据时,其他读 者都不能使用该数 据,这不符合题目 要求。
8.3.4 读者—写者问题
(2) 判定是否是第 个读者 判定是否是第1个读者 希望在读者进程里, 希望在读者进程里,有一个办法能判定请求进入临界区 的是否是第1个读者。如果是第1个读者 个读者, 的是否是第 个读者。如果是第 个读者,就对信号量 wrt做 个读者 做 P操作, 以取得和写者的互斥 ; 如果是后继读者 , 就不再对 操作,以取得和写者的互斥;如果是后继读者, 操作 wrt 做P操作。 操作。 操作 为此, 它不是信号量)初值为 为此 , 设变量 first(它不是信号量 初值为 。 任何一个 它不是信号量 初值为0。 读者运行时,都先在first上加 ,然后判定它是否取值为 。 上加1,然后判定它是否取值为1。 读者运行时,都先在 上加 若是1,则做 否则不做。如图所示。 若是 ,则做P(wrt) ,否则不做。如图所示。
哲学家进餐问题(操作系统)
哲学家进餐问题(操作系统)哲学家进餐问题(操作系统)介绍:哲学家进餐问题是一个经典的并发算法问题,旨在解决多个哲学家在共享资源(餐叉)上发生死锁的可能性。
这个问题可以帮助我们理解操作系统中的并发问题和资源分配策略。
1、问题描述问题中有N个哲学家坐在一个圆桌周围,每个哲学家面前有一盘食物和一支餐叉。
哲学家的生活可以分为思考和进餐两个状态。
当哲学家进餐时,他需要同时拿起他左右两边的餐叉,进食完毕后再放下餐叉进行思考。
2、算法设计为了解决哲学家进餐问题中的死锁问题,可以采用以下算法设计:2.1、餐叉限制为了避免死锁问题,可以引入餐叉限制策略。
每个哲学家一开始只能拿起右手边的餐叉,在用餐完毕后再放下餐叉,然后才能拿起左手边的餐叉。
这样,如果每个哲学家都只拿起右手边的餐叉,不会出现餐叉死锁的情况。
2.2、同时判断两个餐叉是否可用为了避免哲学家同时拿起两个餐叉造成资源竞争问题,可以引入一个全局锁,每次只有一个哲学家可以同时判断两个餐叉是否可用并取走。
3、代码实现以下是解决哲学家进餐问题的伪代码实现:```initialize();while (true) {think(); // 哲学家思考pickup_forks(); // 拿起餐叉eat(); // 哲学家进食putdown_forks(); // 放下餐叉}```4、系统流程图以下是哲学家进餐问题的系统流程图:(此处添加哲学家进餐问题的系统流程图)5、相关附件本文档未附带相关附件,请根据实际需求添加。
6、法律名词及注释本文档没有涉及法律名词及注释。
操作系统哲学家进餐问题
操作系统实习报告一、设计目的:死锁是进程并发执行过程中可能出现的现象,所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局。
哲学家就餐问题是描述死锁的经典例子。
为了防止死锁,可以采用资源预分配法或者资源按序分配法。
资源预分配法是指进程在运行前一次性地向系统申请它所需要的全部资源,如果系统当前不能够满足进程的全部资源请求,则不分配资源, 此进程暂不投入运行,如果系统当前能够满足进程的全部资源请求, 则一次性地将所申请的资源全部分配给申请进程。
二、设计内容哲学家进餐问题的模拟。
三、开发环境windows环境,Myeclipse平台。
四、分析设计<一>实验原理哲学家进餐问题描述的是五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五只碗和五只筷子。
他们的生活方式是交替地进行思考和进餐。
平时,一个哲学家进行思考,饥饿时便试图取用其左右的最靠近他的筷子,只有在他拿到两只筷子时才能进餐。
进餐完毕放下筷子继续思考。
由于:①只有拿到两只筷子时,哲学家才能吃饭;②如果筷子已经在他人手上,则该哲学家必须等到他人吃完之后才能拿到筷子;③任何一个哲学家在自己没有拿到两只筷子吃饭之前,决不放下自己手中的筷子。
则可能出现五个哲学家都饥饿时都拿着一直筷子。
这样就可能五个哲学家都用不上餐。
该问题可用记录型信号量解决,经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用,为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,由这五个信号量组成信号量数组。
当哲学家饥饿时总是先拿其左边的筷子,成功后,再去拿右边的筷子,又成功后方可就餐。
进餐完,又先放下他左边的筷子,再放下右边筷子。
这个算法可以保证不会有两个相邻的哲学家同时就餐,但有可能引起死锁。
对于死锁问题可采取这样的几种解决方法:(1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家可以进餐,最终总会释放出他所用过的两只筷子,从而可使更多的哲学家进餐;(2)仅当左右两只筷子均可用时,才允许哲学家拿起筷子就餐(3)规定奇数号哲学家先拿起右边筷子,然后再去拿左边筷子,而偶数号哲学家则相反。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
改进后的算法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]);
{
think( );
/*哲学家正在思考*/
take_fork(i);
/*取左侧的筷子*/
take_fork((i+1) % N); /*取右侧筷子;%为取模运算*/
eat( );
/*吃饭*/
put_fork(i);
/*把左侧筷子放回桌子*/
put_fork((i+1) % N); /*把右侧筷子放回桌子*/
semaphore fork[5]={1,1,1,1,1};
void philosopher(int i)
{
while(true)
{
think();
if(i%2 == 0)
//偶数哲学家,先右后左。
{
wait (fork[ i + 1 ] mod 5) ;
wait (fork[ i]) ;
eat();
}
}
算法分析:
当出现以下情形,在某一个瞬间,所 有的哲学家都同时启动这个算法,拿起左 侧的筷子,而看到右侧筷子不可用,又都 放下左侧筷子,等一会儿,又同时拿起左 侧筷子……如此这样永远重复下去。对于 这种情哲学家同时进餐,以保 证至少有一个哲学家能够进餐,最终总会释 放出他所使用过的两支筷子,从而可使更多 的哲学家进餐。
}
}
综上所述,解决这一类问题的关键是 找出对应的控制关系,设定相应的控制信 号量。另外,产生死锁是在用信号量进行 流程控制过程中常会遇到的一个问题,因 此如何避免死锁就是解决该类问题的关 键。
Thank you!
哲学家进餐问题
主讲人:次仁桑珠
问题描述
设有五个哲学家,共用一张放有五把椅子 的餐桌,每人坐在一把椅子上,桌子上有五个 碗和五只筷子,每人两边各放一只筷子。哲学 家们是交替思考和进餐,饥饿时便试图取其左 右最靠近他的筷子。
0 1
4
3
2
(1) 只有拿到两只筷子时,哲学家才能吃饭。 (2) 如果筷子已被别人拿走,则必须等别人吃完之后才能拿 到筷子。
signal (fork[ i + 1 ] mod 5) ;
signal (fork[ i]) ;
}
Else
//奇数哲学家,先左后右。
{
wait (fork[ i]) ;
wait (fork[ i + 1 ] mod 5) ;
eat();
signal (fork[ i]) ;
signal (fork[ i + 1 ] mod 5) ;
怎样才能保证哲学家不被饿死呢?
摘 要:解决“哲学家进餐”问题首先要找出对应的
控制关系,设定相应的控制信号量。避免死锁也是解 决该类问题的关键。
关键词:进程同步;信号量;临界资源;临界区; 死锁
算法 A
void philosopher(int i) /*i:哲学家编号,从0 到4*/
{
while (TRUE)
//请求右手边的筷子
eat();
signal(fork[(i+1)%5]);
//释放右手边的筷子
signal(fork[i]);
//释放左手边的筷子
signal(room);
//退出房间释放信号量room
}
}
算法 B 思想
规定奇数号的哲学家先拿起他左边的筷子,然 后再去拿他右边的筷子;而偶数号的哲学家则相反. 按此规定,将是1,2号哲学家竞争1号筷子,3,4号哲 学家竞争3号筷子.即五个哲学家都竞争奇数号筷 子,获得后,再去竞争偶数号筷子,最后总会有一个 哲学家能获得两支筷子而进餐。而申请不到的哲 学家进入阻塞等待队列,根据FIFO原则,则先申 请的哲学家会较先可以吃饭,因此不会出现饿死 的哲学家。