#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <pthread.h> #include <errno.h> #include <math.h> //筷子作為mutex pthread_mutex_t chopstick[6] ;//定義以筷子為鎖的數組 void *eat_think(void *arg) { char phi = *(char *)arg; //將任意類型的指針*arg轉化為*char類型 int left,right; //左右筷子的編號 switch (phi){ case 'A': left = 5; right = 1; break; case 'B': left = 1; right = 2; break; case 'C': left = 2; right = 3; break; case 'D': left = 3; right = 4; break; case 'E': left = 4; right = 5; break; } int i; for(;;){ usleep(3); //思考,將進程掛起一段時間 pthread_mutex_lock(&chopstick[left]); //拿起左手的筷子,鎖定互斥量,加鎖 printf("Philosopher %c fetches chopstick %d\n", phi, left);輸出哲學家拿起了左手邊的筷子 if (pthread_mutex_trylock(&chopstick[right]) == EBUSY){ //判斷右手的筷子是否有人用, 再試一次獲得對互斥量的鎖定(非阻塞) pthread_mutex_unlock(&chopstick[left]); //如果右邊筷子被拿走放下左手的筷子,解鎖互斥量,解鎖 continue;//如果此哲學家沒能吃飯,驗證下一個哲學家是否能吃飯,即跳出本次循環進行下次循環 } // pthread_mutex_lock(&chopstick[right]); //拿起右手的筷子,如果想觀察死鎖,把上一句if注釋掉,再把這一句的注釋去掉 printf("Philosopher %c fetches chopstick %d\n", phi, right); //輸出此哲學家又拿起了右手邊的跨子 printf("Philosopher %c is eating.\n",phi);//輸出此次的哲學家拿起啦一雙筷子在吃飯 usleep(3); //吃飯,把進程掛起一段時間 pthread_mutex_unlock(&chopstick[left]); //放下左手的筷子 printf("Philosopher %c release chopstick %d\n", phi, left); pthread_mutex_unlock(&chopstick[right]); //放下右手的筷子 printf("Philosopher %c release chopstick %d\n", phi, right); } } int main(){ pthread_t A,B,C,D,E; //5個哲學家 int i; for (i = 0; i < 5; i++) pthread_mutex_init(&chopstick[i],NULL);//初始化默認互斥鎖屬性的互斥鎖數組chopstick[i],默認屬性為快速互斥鎖 pthread_create(&A,NULL, eat_think, "A");////創建並跳轉到線程函數創建並跳轉到參數為指向線程標識符的指針為 A 線程函數eat_think,A是運行函數的參數 pthread_create(&B,NULL, eat_think, "B"); pthread_create(&C,NULL, eat_think, "C"); pthread_create(&D,NULL, eat_think, "D"); pthread_create(&E,NULL, eat_think, "E"); pthread_join(A,NULL);//等待線程標識符為 A 的eat_think線程函數結束 pthread_join(B,NULL); pthread_join(C,NULL); pthread_join(D,NULL); pthread_join(E,NULL); return 0; }