5位哲学家进餐的问题
模拟5位哲学家进餐的问题2008-04-21 21:241)问题描述学操作系统的进程同步都要涉及到三个经典问题:生产者-消费者问题、读者-写者问题和哲学家就餐问题。下面来介绍一下哲学家就餐问题: 哲学家就餐问题中,一组哲学家围坐在一个圆桌旁,每个哲学家的左边都只有一只筷子(当然他的右边也有一只筷子,但是这是他右边哲学家的左边的筷子),他们吃完了就思考,思考了一会就会饿,饿了就想吃,然而,为了吃饭,他们必须获得左边和右边的筷子。当每个哲学家只拿有一只筷子的时候,会坐者等另一只筷子,在每个哲学家都只拿一个筷子的时候,就会发生死锁。用C或C++, 来模拟5位哲学家进餐的问题。2)关于源码的一点说明:vc6下源码测试通过运行,不过不能模拟死锁为每个哲学家使用POSIX线程(pthread)建立独立的线程(有独立的id),用互斥(叉子其他哲学家使用时,另一个哲学家不能使用)和条件(哲学家饿了才尝试去得到叉子,得到相邻的左右两把叉子才能进餐)来分到叉子。 关键事件:1. 哲学家饿了就要尝试去得到叉子。2. 哲学家得到相邻的左右两把叉子才可以进餐3. 吃完了就要释放两把叉子每个事件发生就打印一行。并用gettimeofday()显示毫秒 。A. 用'X' 表示哲学家在进餐B. 用'O' 表示哲学家在思考C. 用'!' 表示哲学家饿了例子:1 2 3 4 50 ms: O O O O O95 ms: ! O O O O95 ms: X O O O O214 ms: X O O O !327 ms: X O O ! !328 ms: X O O X !444 ms: O ! O O !444 ms: O X O O X(注意:肯定不会有两个X出现在相邻的列中)程序在运行“50次成功进餐”发生后停止。哲学家在“进餐”和“思考”的“时间周期”是一个0.1到0.5之间的随机数字。5个哲学家都从思考开始。可以考虑使用usleep()还可以使用旗语(semaphore)的 P() 和 V()来解决互斥、#include #include #include enum PhState{Thinking=0,Waiting,Eating};//哲学家状态int stick[5];//筷子状态,1表示使用,0表示空闲PhState phstate[5];//哲学家状态int timerforPh[5];// 定时器,确定状态变化的时刻const int SPAN = 91;//定义思考和进食的最长时间//模拟当i饥饿时,采用的策略。void hungry(int i){int left = (i)%5;int right = (i+1)%5;if(stick[left]==0 && stick[right]==0){stick[left]=stick[right]=1;phstate[i]=Eating;timerforPh[i]=rand()%SPAN+1;//设置吃饭时间}else{phstate[i]=Waiting;}}//从等待中唤醒void wakeup(int i){//唤醒后的操作同思考时饥饿的操作相同hungry( i);}//模拟吃完后的动作void ate(int i){stick[(i)%5]=0;stick[(i+1)%5]=0;//唤醒左右哲学家的顺序可以改成随机的,这里仅仅是固定顺序if(phstate[(5+i-1)%5]==Waiting)wakeup((5+i-1)%5);if(phstate[(i+1)%5]==Waiting)wakeup((i+1)%5);phstate[i]=Thinking;timerforPh[i]=rand()%SPAN+1;//设置思考时间}//输出当前状态,参数为当前时间void print_state(int cur_time){char state_ch[]={'0','!','X'};cout.width(4);cout