linux c語言 哲學家進餐—信號量PV方法一
1、實驗原理
由Dijkstra提出並解決的哲學家進餐問題(The Dinning Philosophers Problem)是典型的同步問題。該問題是描述有五個哲學家共用一張圓桌,分別坐在周圍的五張椅子上,在圓桌上有五個碗和五隻筷子,他們的生活方式是交替地進行思考和進餐。平時,一個哲學家進行思考,飢餓時便試圖取用其左右最靠近他的筷子,只有在他拿到兩隻筷子時才能進餐。進餐完畢,放下筷子繼續思考。
2.實驗內容:
顯示出每個哲學家的工作狀態,如吃飯,思考。連續運行30次以上都未出現死鎖現象。
3.分析解決方案一:
現在引入問題的關鍵:這些哲學家很窮,只買得起五根筷子。他們坐成一圈,兩個人的中間放一根筷子。哲學家吃飯的時候必須同時得到左手邊和右手邊的筷子。如果他身邊的任何一位正在使用筷子,那他只有等着。所以我們就假設最多只有4民哲學家在進餐這樣就能保證沒有死鎖的情況。
代碼如下:
1 #include<unistd.h> 2 #define NUM 5 3 int ID[NUM]={0,1,2,3,4}; 4 sem_t sem_chopsticks[NUM]; 5 sem_t sem_eaters; 6 int eaters_num=0;//記錄已經吃過飯的次數 7 8 //初始化信號量函數 9 void sem_signal_init(){ 10 int i; 11 for(i=0;i<NUM;i++){ 12 if(sem_init(&sem_chopsticks[i],0,1)==-1){ 13 perror("oops:em_init error!"); 14 exit(1); 15 } 16 } 17 if(sem_init(&sem_eaters,0,NUM-1)==-1){ 18 perror("oops:em_init error!"); 19 exit(1); 20 } 21 22 23 } 24 25 26 27 //執行函數,每個線程相當於一個哲學家 來進行 28 void * philosopher(void *ptid){ 29 int pthread_id=*(int *)ptid%NUM; 30 printf("%d philosopher is thinking...\n",(int)pthread_id); 31 sem_wait(&sem_eaters); 32 //申請左筷子 33 sem_wait(&sem_chopsticks[pthread_id]); 34 printf("%d philosopher takes chopstick %d...\n",(int)pthread_id,(int)pthread_id); 35 //申請右筷子 36 sem_wait(&sem_chopsticks[(pthread_id+1)%NUM]); 37 printf("%d philosopher takes chopstick %d...\n",(int)pthread_id,((int)pthread_id+1)%NUM); 38 printf("%d philosopher is eating, %d philosopher had already dined.\n",(int)pthread_id,eaters_num); 39 sem_post(&sem_chopsticks[(pthread_id+1)%NUM]) ; 40 sem_post(&sem_chopsticks[pthread_id]); 41 sem_post(&sem_eaters); 42 eaters_num++;//吃過一次的人加加 43 printf("%d philosopher had dined, by now %d philosopher had already dined.\n",(int)pthread_id,eaters_num); 44 45 } 46 47 48 49 50 int main(int argc,char *argv[]){ 51 int i,l,j,k; 52 //循環五個線程多少次 53 for(l=0;l<1;++l){ 54 printf("*******%d times try *******",l+1); 55 pthread_t philosopher_threads[NUM]; 56 sem_signal_init(); 57 //循環創建五個線程並執行 58 for(i=0;i<NUM;i++){ 59 60 printf("%d times\n",i); 61 if(pthread_create(&philosopher_threads[i],NULL,philosopher,&ID[i])!=0){ 62 perror("oops:pthread_create error!"); 63 exit(1); 64 65 } 66 67 68 } 69 70 //父線程等待子線程都結束才繼續執行 71 for(j=0;j<NUM;j++){ 72 pthread_join(philosopher_threads[j],NULL); 73 } 74 //結束銷毀信號量 75 sem_destroy(&sem_eaters); 76 for(k=0;k<NUM;++k){ 77 sem_destroy(&sem_chopsticks[k]); 78 } 79 eaters_num=0; 80 sleep(2); 81 82 83 } 84 85 86 87 return 0; 88 }
運行結果如下:
1 philosopher is thinking... 0 philosopher takes chopstick 0... 3 times 1 philosopher takes chopstick 1... 2 philosopher is thinking... 4 times 1 philosopher takes chopstick 2... 1 philosopher is eating, 0 philosopher had already dined. 3 philosopher is thinking... 4 philosopher is thinking... 1 philosopher had dined, by now 1 philosopher had already dined. 2 philosopher takes chopstick 2... 0 philosopher takes chopstick 1... 0 philosopher is eating, 1 philosopher had already dined. 4 philosopher takes chopstick 4... 3 philosopher takes chopstick 3... 0 philosopher had dined, by now 2 philosopher had already dined. 4 philosopher takes chopstick 0... 4 philosopher is eating, 2 philosopher had already dined. 4 philosopher had dined, by now 3 philosopher had already dined. 3 philosopher takes chopstick 4... 3 philosopher is eating, 3 philosopher had already dined. 3 philosopher had dined, by now 4 philosopher had already dined. 2 philosopher takes chopstick 3... 2 philosopher is eating, 4 philosopher had already dined. 2 philosopher had dined, by now 5 philosopher had already dined. -------------------------------- Process exited after 2.127 seconds with return value 0 請按任意鍵繼續. . .
後續方案將繼續更新請關注!!!