生活随笔
收集整理的這篇文章主要介紹了
哲学家就餐(避免死锁)(多进程版)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
哲學家就餐(避免死鎖)(多進程版)
哲學家就餐利用信號量在多進程之間實現
下面展示一些代碼片段
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <semaphore.h>int main()
{pid_t pid
;int i
;sem_t
*s
;int left
,right
;int ret
;int flag
= 10;s
= mmap(NULL,sizeof(sem_t
)*5,PROT_READ
|PROT_WRITE
,MAP_SHARED
|MAP_ANON
,-1,0);for(i
= 0;i
<5;i
++){sem_init(&s
[i
],1,1);}for(i
=0;i
<5;i
++){pid
= fork();if(pid
== 0)break;else if(pid
< 0){perror("fork:");exit(1);}}if(i
<5){if(i
== 4){left
= 0; right
= i
;}else{left
= i
;right
= i
+1;}while(flag
--){sem_wait(&s
[left
]);ret
= sem_trywait(&s
[right
]);if(ret
== 0){printf("%dth get sem,pid = %d\n",i
,getpid());sleep(1);sem_post(&s
[right
]);printf("------%dth post right %d sem,pid = %d\n",i
,right
,getpid());sem_post(&s
[left
]);printf("------%dth post left %d sem,pid = %d\n",i
,left
,getpid());sleep(1);}else{sem_post(&s
[left
]);printf("---------------%dth post left %d sem,pid = %d\n",i
,left
,getpid());sleep(1);}}}else{for(i
= 0;i
<5;i
++){pid
= waitpid(-1,NULL,0);if(pid
!= -1){printf("wait child %d,pid = %d\n",i
,pid
);}}for(i
= 0;i
<5;i
++){ret
= sem_destroy(&s
[i
]); if(ret
== 0)printf("destroy sem success %d\n",i
);}}return 0;
}
運行結果截圖:
可以看到程序運行時,進程交替獲得信號量。
哲學家輪流拿到左右兩個筷子(兩個信號量)然后進行就餐,用完就post釋放擁有的兩個筷子(兩個信號量),如果只獲得一個筷子(一個信號量),則放棄之前得到的一個筷子(信號量)。
【重點注意】:
直接將sem_t s[5]放在全局位置,試圖用于子進程間共享是錯誤的!應將其定義放置與mmap共享映射區中。
進程之間不能定義全局信號量,因為進程間全局變量是讀時共享,寫時復制,所以我們可以利用mmap函數建立映射區來實現多進程之間對信號量的操作。
使用方式:將s當成數組首地址看待,與使用數組s[5]沒有差異。
總結
以上是生活随笔為你收集整理的哲学家就餐(避免死锁)(多进程版)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。