哲学家就餐问题实验报告

合集下载

6个哲学家进餐问题预防死锁

6个哲学家进餐问题预防死锁

红河学院课程设计报告操作系统课程名称:6个哲学家进餐设计题目:院系:工学院专业:计算机科学与技术班级:11计科班曹永前设计者:学号:201101030466指导教师:韦相2013 年 5 月26 日1. 问题描述:一个房间内有6个哲学家,他们的生活就是思考和进食。

哲学家思考后,过一定的时间就会饥饿,饥饿之后就想吃饭,吃饭后再思考。

房间里有一张圆桌,桌子周围放有五把椅子,分别属于五位哲学家每两位哲学家之间有一把叉子,哲学家进食时必须同时使用左右两把叉子。

2. 问题分析1、写出哲学家进餐的算法描述。

用六只筷子解决需要用两双筷子来进餐的六个哲学家,由于每个哲学家都需要其周围的两只筷子,所以筷子是公用信号量,这久需要设置一个互斥信号量,来使六个哲学家互斥的进餐.具体做法将六个信号量设置为0-5,用pv 源于来控制信号量,并将六个哲学家分别编号为0-5.经过仔细分析我们会发现,有这样一个问题存在,就是当每个哲学家都申请到他周围的一只筷子时,由于他们每人都只有一只筷子无法进餐,没有进餐他们就无法释放他们已经得得到的筷子,这样是进餐出于一种僵局,无法继续下去,这就是死锁问题.2、死锁问题的分析与具体的解决方法。

死锁问题就是当每个哲学家都拿到且只拿到一只筷子,这样每个哲学家都无法进餐,也无法释放所得到的筷子,所以解决死锁我们就要从这入手,就是怎样去预防使所有哲学家不要同时去申请他们同一方向的筷子.根据这解决死锁的方法有以下几种:a.每一次最多只能有五个哲学家申请进餐.这样其中的一个哲学家就能申请到两只筷子,就能够进餐,再将筷子释放给其他哲学家进餐.b.用AND信号量,就是哲学家需同时申请其左右两边的筷子,两边都有资源的时候,才能让这个哲学家得到资源,这样哲学家只要申请到筷子就能进餐, 再将筷子释放给其他哲学家进餐.c.用管程机制来实现。

d.我们前面已经将每个哲学家都分配了一个编号,我们可以编号为奇数的哲学家首先去申请其左边的筷子,再去申请其右手边的筷子;让编号为偶数的哲学家,先去申请其右边的筷子,再去申请其左边的筷子.我们可以看出编号为奇数的哲学家左边,与编号为偶数的哲学家的右边为同一只筷子,当其中一个哲学家拿到此筷子后,他另一边的筷子也是空闲的,这样就能避免死锁.主程序中我使用的是最后一种避免死锁的方法.3、用C程序实现哲学家进餐。

广东海洋大学 哲学家就餐问题

广东海洋大学  哲学家就餐问题

GDOU-B-11-112广东海洋大学学生实验报告书(学生用表)实验名称哲学家就餐问题课程名称计算机操作系统学院(系) 数学与计算机学院专业班级学生姓名学号实验地点实验日期实验哲学家就餐问题1.1.1服务生解法一个简单的解法是引入一个餐厅服务生,哲学家必须经过他的允许才能拿起餐叉。

因为服务生知道哪只餐叉正在使用,所以他能够作出判断避免死锁。

为了演示这种解法,假设哲学家依次标号为A至E。

如果A和C在吃东西,则有四只餐叉在使用中。

B坐在A和C之间,所以两只餐叉都无法使用,而D和E之间有一只空余的餐叉。

假设这时D想要吃东西。

如果他拿起了第五只餐叉,就有可能发生死锁。

相反,如果他征求服务生同意,服务生会让他等待。

这样,我们就能保证下次当两把餐叉空余出来时,一定有一位哲学家可以成功的得到一对餐叉,从而避免了死锁。

1.1.2资源分级解法另一个简单的解法是为资源(这里是餐叉)分配一个偏序或者分级的关系,并约定所有资源都按照这种顺序获取,按相反顺序释放,而且保证不会有两个无关资源同时被同一项工作所需要。

在哲学家就餐问题中,资源(餐叉)按照某种规则编号为1至5,每一个工作单元(哲学家)总是先拿起左右两边编号较低的餐叉,再拿编号较高的。

用完餐叉后,他总是先放下编号较高的餐叉,再放下编号较低的。

在这种情况下,当四位哲学家同时拿起他们手边编号较低的餐叉时,只有编号最高的餐叉留在桌上,从而第五位哲学家就不能使用任何一只餐叉了。

而且,只有一位哲学家能使用最高编号的餐叉,所以他能使用两只餐叉用餐。

当他吃完后,他会先放下编号最高的餐叉,再放下编号较低的餐叉,从而让另一位哲学家拿起后边的这只开始吃东西。

尽管资源分级能避免死锁,但这种策略并不总是实用的,特别是当所需资源的列表并不是事先知道的时候。

例如,假设一个工作单元拿着资源3和5,并决定需要资源2,则必须先要释放5,之后释放3,才能得到2,之后必须重新按顺序获取3和5。

对需要访问大量数据库记录的计算机程序来说,如果需要先释放高编号的记录才能访问新的记录,那么运行效率就不会高,因此这种方法在这里并不实用。

操作系统哲学家问题实验报告

操作系统哲学家问题实验报告

实验报告三实验名称:一、调试验证“有限缓冲”经典同步问题二、利用Java同步解决“哲学家进餐”问题日期:2015-11-5 班级:13级计科学号:姓名:一、实验目的1.了解信号量的使用2.掌握正确使用同步机制的方法3.实现生产者消费者进程的互斥与同步4.实现java同步解决“哲学家进餐”问题二、实验内容1.调试验证“有限缓冲”经典同步问题2.利用Java同步解决“哲学家进餐”问题三、项目要求与分析1.“有限缓冲”经典同步问题(1)问题描述有一群生产者进程在生产产品,此产品提供给消费者去消费。

为使生产者和消费者进程能并发执行,在它们之间设置一个具有n个缓冲池,生产者进程可将它所生产的产品放入一个缓冲池中,消费者进程可从一个缓冲区取得一个产品消费。

(2)问题分析设两个同步信号量:一个说明空缓冲区的数目,用empty表示,初值为有界缓冲区的大小N,另一个说明已用缓冲区的数目,用full表示,初值为0。

由于在执行生产活动和消费活动中要对有界缓冲区进行操作。

有界缓冲区是一个临界资源,必须互斥使用,所以另外还需要设置一个互斥信号量mutex,其初值为1。

2.“哲学家进餐”问题(1)问题描述假如所有的哲学家都同时拿起左侧筷子,看到右侧筷子不可用,又都放下左侧筷子,等一会儿,又同时拿起左侧筷子,如此这般,永远重复。

对于这种情况,即所有的程序都在无限制地运行,但是都无法得到任何进展,即出现饿死,所有的哲学家都吃不上饭。

规定在拿起左侧的筷子后,先检查右面的筷子是否可用。

如果不可用,则放下左侧的筷子,等一段时间后再重复整个过程。

(2)问题分析当出现以下情形,在某一瞬间,所有的哲学家都同时启用这个算法,拿起左侧的筷子,而看到右侧筷子都不可用,又都放下左侧筷子,等一会儿,又同时拿起左侧筷子……如此永远重复下去。

对于这种情况,所有的程序都在运行,但却都无法取得进展,即出现饿死,所有的哲学家都吃不上饭。

解决死锁问题:为了避免死锁,把哲学家分为三种状态:思考,饥饿(等待),进食,并且一次拿起两只筷子,否则不拿。

哲学家就餐问题实验报告

哲学家就餐问题实验报告

南昌大学实验报告学生姓名:倪焕学号: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. 类、对象、继承及多态实验目的:理解Java对象的面向对象的特征以及在编程中的应用。

实验内容:1、验证对象作为参数传递是引用传递,而普通数据类型为值传递。

2、验证构造方法和静态属性与方法专属于类,而其他属性和方法虽然在类中定义,但是为对象而定义。

3、验证子类对象实例化时,通过继承,不仅将public、protected、缺省的属性和方法拷贝到对象当中,也将父类的私有属性拷贝到对象当中。

4、编写程序,体会类在重载情况下的相互调用,体会构造方法重载的调用方式。

5、编程体现this的三种用法,super的两种用法,指出this.属性在什么情况下不可以省略,指出super.成员方法在什么情况下不能省略,指出this指代对象的作用。

6、设计Src和Dis两个类, Src中有一个被封装的属性,类型为int(要求为非负值),每当我们通过特定方法更改Src对象中的这个属性后,Dis对象都能得到通知,并向Src发消息获得此属性值实验要求:1、程序以能证明和说明实验内容当中提出的问题为实现标准。

2、程序应有良好的书写规范,在类名定义、包名定义、变量定义、常量定义上遵从规范,同时程序在书写上应有良好的缩进层次。

3、实验报告中应有实验体会和收获等方面。

准备工具:1、JDK1.3以上版本,设置环境变量,搭建编译和运行环境。

1、搭建环境。

2、选用Application进行验证。

实验3. 多线程综合设计实验目的:理解Java语言中的多线程和异常处理,并将二者结合起来设计一个综合程序,实现特定的应用功能。

实验内容:1、7名哲学家同桌就餐,演示哲学家就餐问题中死锁现象的出现,并说明原因2、给出一种解决方案,保证多线程下不出现死锁,并说明这样实现的理由实验要求:1、必须有多线程和异常的内容,其中多线程需要处理多线程同步,如还有同步通信则更好;异常需要有异常抛出、异常捕获、异常嵌套捕获等内容,如有自定义异常类则更好。

2、程序当中产生异常的点很多,在一个大的应用程序当中(有众多的类),无论哪种异常发生后,如何集中在一处统一给出中文提示。

哲学家就餐问题实验报告

哲学家就餐问题实验报告

哲学家就餐问题实验报告姓名:何绍金班级:自动化1202学号:201203870408指导教师:张健2014年11月22日一.实验题目经典的同步问题——哲学家就餐问题设计。

二.实验内容1.实验要求有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子每个哲学家的行为是思考,感到饥饿,然后吃通心粉.为了吃通心粉,每个哲学家必须拿到两只筷子,并且每个人只能直接从自己的左边或右边去取筷子。

2.程序流程图图1.主程序模块流程图开始定义信号量tools[5] 定义哲学家类对象P1-P5哲学家的状态发生改变;P1.change();P2.change();P3.change();P4.change();P5.change()输出当前状态停止程序结束否图2.状态改变模块流程图哲学家处于的状态否 哲学家处于思考状态是状态改为等待否 哲学家处于等待是 左右手筷子均空闲是 拿起左右手筷子状态改为就餐结束开始是 放下左右手工具 状态为思考 Status==2图3.返回哲学家状态流程图图4返回餐具状态模块流程图3.测试结果图5 测试结果1图6 测试结果2图7 测试结果34.结果分析和小结(1)程序分为四大模块,一步步解决了哲学家状态及状态改变的问题,筷子的“闲”、“用”问题;实现了哲学家等待、吃饭、思考三个过程的转换循环,并且避免了死锁问题;让临界资源得到了充分的利用。

(2)这次实验让我学会分模块解决问题,怎样运用互斥锁对临界资源进行管理;此外自己在编程上及一些函数的认识仍存在较大的问题,以后应该多多实践,提高自己的反应速度,加强逻辑思维能力。

三.程序源代码#include <windows.h>#include <time.h>#include <string>#include <iostream>#include <assert.h>using namespace std;bool tools[5]; //全局变量,用餐工具CRITICAL_SECTION cs; //信号量, 在线程中使用,临界区class Philosopher{private:int number;int status; /*标记当前哲学家的状态,0表示正在等待(即处于饥饿状态),1表示得到两支筷子正在吃饭,2表示正在思考*/public:Philosopher(int num=0): status(2), number(num) { }const int find(){return number;}const int getinfo(){ return status; }void Change() ; //状态改变函数void dead_lock();};/////////void Philosopher::dead_lock(){EnterCriticalSection (&cs) ; //进入临界区string s;if(status==1){tools[number%5]=true;// tools[(number-1)%5]=true;status=2;}else if(status==2){status=0;//tools[(number-1)%5]=false;//tools[(number-1)%5]=true;}else if(status==0){tools[number%5]=false;tools[(number-1)%5]=false;status=1;}LeaveCriticalSection (&cs) ;// cout<<"*********";}/////////void Philosopher::Change(){EnterCriticalSection (&cs) ; //进入临界区if(status==1) //正在进餐{tools[number%5]=true; //放下左手工具tools[(number-1)%5]=true; //放下右手工具status=2; //改变状态为思考}else if(status==2) //思考中{status=0; //改变状态为等待}else if(status==0) //等待中{if(tools[number%5]&&tools[(number-1)%5]) //左右手两边工具均为空闲状态{tools[number%5]=false; //拿起左手工具tools[(number-1)%5]=false; //拿起右手工具status=1;}}LeaveCriticalSection (&cs) ;}string print(Philosopher *pA){//pA->Change();int i=pA->getinfo();string str;if(i==0)str="等待";else if(i==1)str="就餐";else str="思考";return str;}string toolstatus(bool a){string state;if(a==true)state="闲";if(a==false)state="用";return state;}int main(){char con='y'; //判断是否继续// con = 'n';for(int i=0;i<5;i++)tools[i]=true; //筷子都未使用,初始化Philosopher P1(1),P2(2),P3(3),P4(4),P5(5);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<<"筷子的状态,用表示使用中,闲表示空闲中。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

南昌大学实验报告
学生姓名:倪焕学号: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; //哲学家id
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);
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操作更加熟悉,同时帮助我理解了原先不太懂的地方,希望强加练习。

相关文档
最新文档