哲學家就餐問題
多執行緒編程中,常常會遇到執行緒間訪問共享資源的問題,如果處理不當則會發生死鎖,某一個執行緒可能永遠訪問不到共享資源,
為了避免死鎖的發生,提出哲學家就餐問題,
下面展示一些代碼片段
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/mman.h>
/* 多執行緒之間通過互斥鎖實作哲學家就餐問題(如何避免死鎖)
得到兩把鎖則進餐,只得到第一把鎖,得不到第二把鎖則釋放已經擁有的第一把鎖
*/
pthread_mutex_t mutex[5];
void *tfun(void *arg)
{
int left,right;
int i = (int)arg;
int ret;
if(i == 4)
{
left = 0,right = i;
}
else
{
left = i;right = i+1;
}
while(1)
{
pthread_mutex_lock(&mutex[left]);
//利用trylock非阻塞函式,加鎖失敗則立即回傳,不則塞
ret = pthread_mutex_trylock(&mutex[right]);
if(ret == 0)
{
printf("%dth thread get lock\n",i);
sleep(1); //模擬哲學家進餐程序
pthread_mutex_unlock(&mutex[right]);
printf("%dth thread unlock right %d----------------\n",i,right);
pthread_mutex_unlock(&mutex[left]);
printf("%dth thread unlock left %d----------------\n",i,left);
sleep(1);
}
else
{
pthread_mutex_unlock(&mutex[left]);
printf("%dth thread unlock left %d-----------------------------------\n",i,left);
sleep(1);
}
}
pthread_exit(NULL);
}
int main()
{
pthread_t tid[5];//定義五個互斥鎖-對應5只筷子
int i;
for(i=0;i<5;i++)
{
//互斥鎖初始化
pthread_mutex_init(&mutex[i],NULL);
}
for(i=0;i<5;i++)
{
//創建五個執行緒--對應5個哲學家,編號為0-4
pthread_create(&tid[i],NULL,tfun,(void *)i);
}
for(i=0;i<5;i++)
{
pthread_join(tid[i],NULL);
}
for(i=0;i<5;i++)
{
pthread_mutex_destroy(&mutex[i]);
}
return 0;
}
振蕩:如果每個人都攥著自己左手的鎖,嘗試去拿右手鎖,拿不到則將鎖釋放,過會兒五個人又同時再攥著左手鎖嘗試拿右手鎖,依然拿不到,如此往復形成另外一種極端死鎖的現象——振蕩,
程式中哲學家都先去拿左邊的筷子,再拿右邊的筷子,為了避免振蕩,第四個哲學家反其道而行,先拿右邊的筷子,再拿左邊的筷子,
兩個筷子都拿到則進餐,如果只拿到第一個筷子,沒有拿到第二個筷子,則釋放已有的筷子,
避免死鎖的方法:
1:若得不到所有所需的資源時,放棄已經獲得的資源,等待,
2:保證資源的獲取順序,要求每個執行緒獲取資源的順序一致,如:A獲取順序1、2、3;B順序也應該是1、2、3.若B為3、2、1則易出現死鎖的現象,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/262455.html
標籤:其他
