?? 5位 哲學家進餐的問題.txt
字號:
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()來解決互斥、
萬分感激。。。。。。。。。。。。。。。。。。。。。。。
貼一個,不過不能模擬死鎖
#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;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -