執行緒同步三部曲 之哲學家進餐問題,c語言實現

2021-10-05 12:13:45 字數 2407 閱讀 2643

二、對第乙個方案的改正

背景描述

有五個哲學家,他們的生活方式是交替地進行思考和進餐,哲學家們共用一張圓桌,分別坐在周圍的五張椅子上,在圓桌上有五個碗和五支筷子,平時哲學家進行思考,飢餓時便試圖取其左、右最靠近他的筷子,只有在他拿到兩支筷子時才能進餐,該哲學家進餐完畢後,放下左右兩隻筷子又繼續思考。

約束條件:

(1)只有拿到兩隻筷子時,哲學家才能吃飯。

(2)如果筷子已被別人拿走,則必須等別人吃完之後才能拿到筷子。

(3)任一哲學家在自己未拿到兩隻筷子吃完飯前,不會放下手中已經拿到的筷子。

我們要實現的是每個哲學家都有機會拿到左右兩把叉子進行用餐,那麼,可以明確的是叉子成為相鄰哲學家進餐的競爭條件。接下來,我們通過一些操作實現哲學家間取叉子的同步而不產生死鎖。

方案描述

如上圖,對所有哲學家和叉子進行編號,每個哲學家右手的叉子的編號與哲學家編號相同。進餐時,每個哲學家先取得右手的叉子,再取得左手的叉子,方可開始進餐。

下圖是對上述方案的流程描述

到這,不妨思考幾秒鐘,這個方案會產生什麼問題呢?

好了,揭曉漏洞:

這種實現是有可能產生死鎖的,即所有哲學家都拿著右手邊的叉子,都在等待左手邊的叉子,於是每個人都幹等著,誰都吃不到飯。

方案**

#include

#include

#include

#include

#include

#include

#define num 5

int eaters =0;

//-------------------一些訊號量----------------

sem_t sem_fork[num]

;sem_t sem_eaters;

void

sem_mutex_init()

if(sem_init

(&sem_eaters,0,

1)==-

1)return;}

void

philosopher()

}int

main

(void)}

sem_mutex_init()

;for

(i =

0; i < num;

++i)

return0;

}

方案描述

此方案和第乙個方案大同小異。那麼,改正方案通過「單雙號限流」避免死鎖:雙號執行緒先拿右手邊叉子,拿左手邊叉子;單號執行緒先拿左手邊叉子再拿右手邊叉子。

腦補一下,這樣就不會產生死鎖了,對吧

方案**

**和上乙個方案的區別就在philosopher函式裡對執行緒單雙號進行了區別對待

#include

#include

#include

#include

#include

#include

#define num 5

int eaters =0;

//-------------------一些訊號量----------------

sem_t sem_fork[num]

;sem_t sem_eaters;

void

sem_mutex_init()

if(sem_init

(&sem_eaters,0,

1)==-

1)return;}

void

philosopher()

else}}

intmain

(void)}

sem_mutex_init()

;for

(i =

0; i < num;

++i)

return0;

}

筆者才疏學淺,若同學們有更好的想法請不吝賜教,一起**哈!首次編輯 2020-4-26 23:10:58

作業系統執行緒同步之哲學家進餐問題

五個哲學家,五隻筷子,只有獲得一雙筷子之後才能就餐,就有可能出現這種情況 每個哲學家都獲得了乙隻筷子,卡死在那個地方。1 有乙個服務生來負責避免死鎖 2 哲學家在拿筷子的時候,確保左右都有筷子才同時拿起左右兩隻筷子 3 規定拿筷子的方式 給筷子編號,先拿號碼小的筷子 class chopsticks...

經典程序的同步問題之 哲學家進餐

哲學家進餐問題描述 由dijkstra提出並解決哲學家進餐問題 the dinning philosophers problem 是經典的同步問題。該問題是描述有五個哲學家共用一張圓桌,分別坐在周圍的五張椅子上,在桌子上有五個碗和五隻筷子,他們的生活方式是交替的進行思考和進餐。平時,乙個哲學家進行思...

程序同步 互斥 哲學家進餐問題

1 問題描述 一張圓桌上有5名哲學家,沒兩個哲學家之間有一根筷子,桌子中間由一碗公尺飯。當哲學家飢餓時會試圖分別拿起左右兩根筷子,如果筷子已在他人手上則需等待。飢餓的哲學家只有拿起兩根筷子才能進餐,吃完後才能放下筷子。2 問題分析 對哲學家分別編號0,1,2,3,4,對筷子編號0,1,2,3,4。i...