〖高分求解〗★★★★★【C或C++, 来模拟 5位 哲学家进餐的问题。】★★★★★〖up有分〗
C或C++, 来模拟 5位 哲学家进餐的问题:
为每个哲学家使用POSIX线程(pthread)建立独立的线程(有独立的id),用互斥(叉子其他哲学家使用时,另一个哲学家不能使用)和条件(哲学家饿了才尝试去得到叉子,得到相邻的左右两把叉子才能进餐)来分到叉子。
关键事件:
1. 哲学家饿了就要尝试去得到叉子。
2. 哲学家得到相邻的左右两把叉子才可以进餐
3. 吃完了就要释放两把叉子
每个事件发生就打印一行。并用gettimeofday()显示毫秒 。
A. 用'X' 表示哲学家在进餐
B. 用'O' 表示哲学家在思考
C. 用'!' 表示哲学家饿了
例子:
1 2 3 4 5
0 ms: O O O O O
95 ms: ! O O O O
95 ms: X O O O O
214 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()来解决互斥、
万分感激。。。。。。。。。。。。。。。。。。。。。。。
问题点数:100、回复次数:46Top
1 楼goodgod105(不来电)回复于 2006-10-13 09:17:34 得分 2
关注Top
2 楼vcnewer(磨剑)回复于 2006-10-13 09:30:58 得分 2
嘿嘿Top
3 楼snowman1123(雪自轻飘过)回复于 2006-10-13 09:47:12 得分 2
可以这样处理,给5个哲学家编号,1-5,单号的先拿左边,拿到左边再拿右边,如果拿不到左边就停止,不拿右边.同理双号的先拿右边,拿到右边再拿左边,如果拿不到右边就停止,不拿左边.这样无论如何每次总会有人拿到成双的叉子的Top
4 楼leijun8088(日光灯管)回复于 2006-10-13 09:49:26 得分 2
值得学习
关注ing..................................Top
5 楼helpbill()回复于 2006-10-13 09:51:12 得分 0
■■■■■ snowman1123(雪自轻飘过):
■■■■■ 能不能给个代码例子??Top
6 楼watermelontx(晨曦)回复于 2006-10-13 13:55:00 得分 2
关注,期待。。。Top
7 楼yqzq(花心萝卜)回复于 2006-10-13 14:42:20 得分 2
upTop
8 楼yjf7888(seeking a place 找工作了location:Chengdu)回复于 2006-10-13 15:40:28 得分 2
upTop
9 楼scottttocs(大师哥)回复于 2006-10-14 08:21:07 得分 4
main()
{
for( ; ;)
wait(chopstick[i])
wait(chopstick[i+1] mod 5)
.
.
.
do_the_operation;
.
.
.
signal(chopstik[i]);
signal(chopstick[i+1] mod 5);
}
int s;
void wait(int)
{
while (s <= 0)
睡眠;
s = s - 1;
}
void signal(int)
{
s += 1;
}Top
10 楼helpbill()回复于 2006-10-14 08:27:13 得分 0
大家继续完善啊。。。。。
谢谢Top
11 楼universes(及时揭帖是一种美德 | CSDN也这么黑)回复于 2006-10-16 16:06:20 得分 2
markTop
12 楼edison1848()回复于 2006-10-17 12:41:40 得分 2
强烈关注中,
期待高人现身Top
13 楼clliu(阿亮)回复于 2006-10-19 08:49:08 得分 2
期望高手出现,给出个高效的算法。Top
14 楼PleaseDoTellMeWhy(Allah bless you!)回复于 2006-10-19 13:30:42 得分 2
关注中!Top
15 楼songmeiyu()回复于 2006-10-20 12:38:02 得分 2
http://community.csdn.net/Expert/TopicView.asp?id=5079026Top
16 楼shellyyee(☆☆☆☆☆-----疏狂一醉,生活大师)回复于 2006-10-20 13:00:05 得分 2
帮顶...Top
17 楼39457760(人间一日,网上一年◎分要多多的给,贴要慢慢的结)回复于 2006-10-20 20:00:16 得分 60
贴一个,不过不能模拟死锁
#include <stdlib.h>
#include <iostream.h>
#include <time.h>
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<<cur_time<<"ms : ";
for(int i=0; i<5; i++)
{
cout.width(2);
cout<<state_ch[phstate[i]]<<' ';
}
cout<<endl;
}
//模拟器
void simulator()
{
//初始化
srand(time(NULL));
for(int i=0; i<5;i++)
{
stick[i]=0;
timerforPh[i]=rand()%SPAN+1;
phstate[i]=Thinking;
}
//模拟开始
long time = 0; //时钟
int eating_event_cnt=0; //进食成功事件次数
while(eating_event_cnt<50)
{
time++;
//检查哪个哲学家的状态需要改变
for(int i=0;i<5;i++)
{
switch(phstate[i])
{
case Waiting:
++timerforPh[i];//记录等待时间
break;
case Thinking:
if(--timerforPh[i]<0)
{
hungry(i);
print_state(time);
}
break;
default:
if(--timerforPh[i]<0)
{
ate(i);
print_state(time);
eating_event_cnt++;
}
break;
};
}
}
}
int main(int argc, char* argv[])
{
simulator();
return 0;
}
Top
18 楼leijun8088(日光灯管)回复于 2006-10-20 20:46:37 得分 0
//////////////////////////////////////////////////////////
因为这个C++的程序无法在 C 下面运行啊。
能不能那位兄弟帮忙修改一下。
提示 iostream.h: No such file or directory
//////////////////////////////////////////////////////////
Top
19 楼sunbird69(太阳鸟)回复于 2006-10-20 21:51:18 得分 2
markTop
20 楼AvalonXP(阿瓦隆)回复于 2006-10-20 22:27:32 得分 0
是作业题么?
不是不答Top
21 楼stylefree()回复于 2006-10-21 12:44:03 得分 2
其实在linux下也可以用c++编程工具-g++,命令和gcc一样,可以试一试Top
22 楼wucunfu(因为楼主你吝啬,所以我还是一个三角裤衩!)回复于 2006-10-21 14:50:40 得分 2
39457760(人间一日,网上一年) 正解Top
23 楼IMGGTOO(寻找自己的远方)回复于 2006-10-21 21:29:17 得分 2
啊,这不是大四上学期,算法书上的问题吗?
这个问题很复杂啊,凡是上了算法书的问题,如什么背包算法,N皇后算法之类,日难!!!反正我那个时候是没什么心思学那玩意,搞的现在什么高级点的算法都不会,后悔ing...
只能帮你顶一下了!!!Top
24 楼IMGGTOO(寻找自己的远方)回复于 2006-10-21 22:39:07 得分 2
TO: leijun8088(日光灯管) ( ) 信誉:100 Blog
///////////////////////////////////////////////////////////////
因为这个C++的程序无法在 C 下面运行啊。
能不能那位兄弟帮忙修改一下。
提示 iostream.h: No such file or directory
///////////////////////////////////////////////////////////////
这个好象在C++下也不行的,应该是"39457760(人间一日,网上一年) "笔误.改成
#include <iostream>
没有 .h .Top
25 楼xuebee()回复于 2006-11-03 10:58:12 得分 0
有学问,学习下
Top
26 楼vbanglev()回复于 2006-11-03 16:46:15 得分 0
maskTop
27 楼fengfeiwuwq(寒烟翠)回复于 2006-11-03 17:31:30 得分 0
路过Top
28 楼guqst(过关斩将)回复于 2006-11-03 21:07:52 得分 0
操作系统 ANDREW S. TANENBAUM 里就有这个例子...Top
29 楼blueblue_god()回复于 2006-11-03 23:02:31 得分 0
顶,学习了!Top
30 楼ssdx(未来啊未来)回复于 2006-11-04 12:52:04 得分 0
我记得运筹学里面讲过了,都不看书吗?Top
31 楼goldendreams(快乐生活)回复于 2006-11-04 17:38:32 得分 0
长见识了Top
32 楼qozms(Alex)回复于 2006-11-04 20:23:11 得分 0
mark
Top
33 楼zhuoguang(灼光)回复于 2006-11-04 20:25:55 得分 0
恩,不错
学了好多!!Top
34 楼fangfan4060()回复于 2006-11-04 23:21:05 得分 0
这个好象在C++下也不行的,应该是"39457760(人间一日,网上一年) "笔误.改成
#include <iostream>
没有 .h .
这个问题是c++ 的标准化引起的,在2003 ISO前,好像是可以的Top
35 楼windkoo()回复于 2006-11-05 10:05:33 得分 0
死锁的问题,挺有意思的。Top
36 楼seakon()回复于 2006-11-05 10:46:11 得分 0
把<iostream>换下就行了<stdio>
函数也要换Top
37 楼gaiguzi_youmin()回复于 2006-11-05 13:01:27 得分 0
哈哈,去用vc6运行下Top
38 楼wxspll(HDU)回复于 2006-11-05 13:40:46 得分 0
markTop
39 楼dyh1919(→★☆★昵称用来干啥子呢?☆★☆←)回复于 2006-11-05 19:23:58 得分 0
最近正在学这方面的内容.
不过只是了解,还没深入思考过用程序来实现Top
40 楼39457760(人间一日,网上一年◎分要多多的给,贴要慢慢的结)回复于 2006-11-05 19:37:38 得分 0
这个好象在C++下也不行的,应该是"39457760(人间一日,网上一年) "笔误.改成
#include <iostream>
没有 .h .
===============================
我用的是VC6,不怎么符合标准
Top
41 楼dyh1919(→★☆★昵称用来干啥子呢?☆★☆←)回复于 2006-11-05 20:09:17 得分 0
在VC 6.0能成功运行的.
我做了这些修改:
1:将sdio.h和time.h找到,然后拷贝到.c目录中.
2:修改前面部分为:
#include"stdio.h"
#include<iostream>
#include"time.h"
using namespace std;
......
后面的都没做过修改.......
不过对程序的具体实现还是不甚了解,学习.........Top
42 楼39457760(人间一日,网上一年◎分要多多的给,贴要慢慢的结)回复于 2006-11-05 20:21:44 得分 0
符合标准C++标准的头文件写法
#include <ctime>
#include <iostream>
#include <cstdlib>
using namespace std;
想用C编译,需要把iostream去掉,然后里面所有cout有关的都用printf替换
Top
43 楼qingcairousi(青耕)回复于 2006-11-06 08:22:04 得分 0
作业?如果是得话,太偷懒了吧……Top
44 楼bossyu(卡卡)回复于 2006-11-06 12:06:41 得分 0
西安电子科技大学出版的《 操作系统》上面有这个Top
45 楼csShooter(Sharp Shooter)回复于 2006-11-06 14:15:35 得分 0
markTop
46 楼woshiyechao()回复于 2007-01-20 09:19:46 得分 0
哲学家进餐问题演示程序
作者:叶超 E_MAIL:woshiyechao@sohu.com 专业:计算机
一. 界面设计
a) 四个哲学家进餐,分别用四个Shape控件表示,用四个Label控件表示其不同的名称.
b) 四个Button控件,分别用以控制四个哲学家的状态(哲学家的各种不同状态用改变其代表的Shape控件的颜色来表示).
c) 四个餐具(两个刀两个钗),分别用四个Shape控件表示(当有一位哲学家正在用餐Eating时,其左右的餐具消失,表示该餐具处于哲学家手中,下同).
d) 别加两个Button控件,分别用于控制显示帮助Form与退出程序.
二. 编程思路
a) 初始化各个哲学家的状态为Thinking,餐桌上的餐具都在桌上.
b) 通过单击Caption为Change的Button控件来改变其对应的哲学家的状态.单击的先判断该哲学家当前的状态.
i. 当哲学家当前状态为Thinking时,检查其左右的餐具是否空闲(其Visible属性为False时则忙,否则为空闲),如果餐具为空闲,则改变该哲学家的状态为Eating,并改变其左右的餐具(置两个Shape的Visible属性为False,下同);如果餐具为忙,则改变该哲学家的状态为Waiting(启动与该哲学家相对应的Timer控件).
ii. 当哲学家当前状态为Eating时,改变哲学家的状态为Thinking,并放下其手中的餐具(置其左右两个Shape控件的Visible属性为True,下同).
iii. 当哲学家当前状态为Thinking时,提示操作者哲学家当前状态为Thinking,得不到餐具不能进入Eating状态.不改变哲学当前状态.
c) Timer控件的工作原理.Timer控件主要用于,当哲学家要从Thinking状态进入Eating状态时,发现其左右的餐具都为忙时进入Waiting状态.这时哲学家每一秒钟会检查一次其左右的餐具是否为空闲(则是否有足够的餐具以供其进入Eating状态).如果有则改变其状态为Eating,并拿起其左右的餐具,停止当前Timer控件为;如果没有则持续当前状态(即循环执行Timer控件中的程序).
Top




