哲学家进餐的问题

    技术2022-05-11  142

    为每个哲学家使用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)