vc6.0,dev-cpp均可運行
#include<stdio.h>
#include<windows.h>
#include<process.h>
#define N 5 //哲學家個數
#define LEFT(i) ((i) + N - 1) % N //左邊哲學家編號
#define RIGHT(i) ((i) + 1) % N //右邊哲學家編號
#define THINKING 0 //思考狀態
#define HUNGRY 1 //飢餓狀態
#define EATING 2 //就餐狀態
int state[N]; //哲學家狀態數組
HANDLE mutex; //狀態訪問互斥量,保證任一時刻,只有一個哲學家線程在檢查左右兩邊狀態
HANDLE semaphore[N]; //哲學家線程信號量,標識哲學家是否獲取了筷子,否則線程阻塞
HANDLE semPar; //線程同步信號量,
void thinking(int i); //思考
void eating(int i); //吃飯
void take_chopsticks(int i);
void put_chopsticks(int i);
void test(int i); //判斷左右是否有空筷子
unsigned int __stdcall philosopher(void *pM)
{
int i,cnt =20;
i = *(int*)pM;
//線程編號,同步
ReleaseSemaphore(semPar, 1, NULL);
while(cnt--)// 規定每位哲學家用用餐20次後結束
{
thinking(i);
take_chopsticks(i);
eating(i);
put_chopsticks(i);
}
return 0;
}
void take_chopsticks(int i)
{
//互斥修改及檢查哲學家狀態
WaitForSingleObject(mutex, INFINITE);
state[i] = HUNGRY;
test(i);
ReleaseSemaphore(mutex, 1, NULL);
//若獲得了兩隻筷子,則繼續執行,否則阻塞在此處,等待鄰居放下筷子
WaitForSingleObject(semaphore[i], INFINITE);
}
void put_chopsticks(int i)
{
WaitForSingleObject(mutex, INFINITE);
state[i] = THINKING;
test(LEFT(i)); //檢查左邊哲學家是否可以就餐
test(RIGHT(i)); //檢查右邊哲學家是否可以就餐
ReleaseSemaphore(mutex, 1, NULL);
}
void test(int i)
{
if(state[i] == HUNGRY && state[LEFT(i)] != EATING && state[RIGHT(i)] != EATING)
{
state[i] = EATING;
ReleaseSemaphore(semaphore[i], 1, NULL);
}
}
void eating(int i)
{
printf("哲學家[%d]正在吃飯\n", i);
Sleep(3000);
printf("哲學家[%d]已經吃完 放下筷子\n\n", i);
}
void thinking(int i)
{ printf("哲學家[%d]正在思考\n", i);
Sleep(3000);
printf("哲學家[%d]思考完餓了\n\n", i);
}
int main()
{
int i;
HANDLE thread[N];
printf("--------------------------------\n");
printf("- 模擬哲學家進餐 -\n");
printf("********************************\n");
mutex = CreateSemaphore(NULL, 1, 1, NULL); //設定每個哲學家在思考
for(i = 0;i < N;i++)
{
semaphore[i] = CreateSemaphore(NULL, 0, 1, NULL); //將每個信號量賦值
}
semPar = CreateSemaphore(NULL, 0, 1, NULL);
for(i = 0;i <N;i++)
{
thread[i] = (HANDLE)_beginthreadex(NULL, 0,philosopher, &i, 0, NULL);
WaitForSingleObject(semPar, INFINITE);
}
WaitForMultipleObjects(N, thread, TRUE, INFINITE);
return 0;
}