哲学家进餐的问题

为每个哲学家使用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()来解决互斥

#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;
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值