php 哲学家进餐,IPC问题-哲学家就餐(示例代码)
如上圖,有五位哲學(xué)家,盤中的食物只有左右兩個叉子都拿起才能吃。哲學(xué)家在桌上只有思考(等待)和吃面(執(zhí)行)。看起來最多是只有2個人能同時吃。
版本一:這個思路的最糟糕的就是都拿起左邊叉子,那樣都沒法吃了,直接死鎖。
版本二:改進(jìn)版本一,如果拿起左邊叉子,先看右邊是否能用,不可用的話放下左邊叉子等待一段時間再運(yùn)行。這個思路的問題就是,會產(chǎn)生某個時刻每個人都拿起左叉子,又放下,又拿起,雖然沒有死鎖,但是沒有人在吃面,消耗了性能但是任務(wù)沒有進(jìn)展,造成饑餓。
版本三:改進(jìn)版本二,每次等待右邊是否能用的每個哲學(xué)家(線程)時間不一樣,這個方法看起來ok,但是考慮到極度糟糕情況下,它仍不能穩(wěn)定,對于極度要求穩(wěn)定的場合顯然也是不合適的。
版本四:我們可以對think后加一個互斥量,就是在拿起左叉子前,就加上一個互斥量,別人就沒法拿叉子了,放下互斥量在去掉,但問題是性能差,一次只能有一位人吃面,一開始我們就分析過其實可以兩個人同時吃的。
這是新的解法:其實就是在版本四的基礎(chǔ)上對每個要拿起叉子的哲學(xué)家進(jìn)行了left 和 right的饑餓狀態(tài)判斷,只有當(dāng)鄰居都不在飲食的基礎(chǔ)上才能飲食。這樣既不會死鎖也不會饑餓,且性能滿足了。
下面為Wiki的解釋和方法:
服務(wù)生解法
一個簡單的解法是引入一個餐廳服務(wù)生,哲學(xué)家必須經(jīng)過他的允許才能拿起餐叉。因為服務(wù)生知道哪只餐叉正在使用,所以他能夠作出判斷避免死鎖。
為了演示這種解法,假設(shè)哲學(xué)家依次標(biāo)號為A至E。如果A和C在吃東西,則有四只餐叉在使用中。B坐在A和C之間,所以兩只餐叉都無法使用,而D和E之間有一只空余的餐叉。假設(shè)這時D想要吃東西。如果他拿起了第五只餐叉,就有可能發(fā)生死鎖。相反,如果他征求服務(wù)生同意,服務(wù)生會讓他等待。這樣,我們就能保證下次當(dāng)兩把餐叉空余出來時,一定有一位哲學(xué)家可以成功的得到一對餐叉,從而避免了死鎖。
資源分級解法
另一個簡單的解法是為資源(這里是餐叉)分配一個偏序或者分級的關(guān)系,并約定所有資源都按照這種順序獲取,按相反順序釋放,而且保證不會有兩個無關(guān)資源同時被同一項工作所需要。在哲學(xué)家就餐問題中,資源(餐叉)按照某種規(guī)則編號為1至5,每一個工作單元(哲學(xué)家)總是先拿起左右兩邊編號較低的餐叉,再拿編號較高的。用完餐叉后,他總是先放下編號較高的餐叉,再放下編號較低的。在這種情況下,當(dāng)四位哲學(xué)家同時拿起他們手邊編號較低的餐叉時,只有編號最高的餐叉留在桌上,從而第五位哲學(xué)家就不能使用任何一只餐叉了。而且,只有一位哲學(xué)家能使用最高編號的餐叉,所以他能使用兩只餐叉用餐。當(dāng)他吃完后,他會先放下編號最高的餐叉,再放下編號較低的餐叉,從而讓另一位哲學(xué)家拿起后邊的這只開始吃東西。
盡管資源分級能避免死鎖,但這種策略并不總是實用的,特別是當(dāng)所需資源的列表并不是事先知道的時候。例如,假設(shè)一個工作單元拿著資源3和5,并決定需要資源2,則必須先要釋放5,之后釋放3,才能得到2,之后必須重新按順序獲取3和5。對需要訪問大量數(shù)據(jù)庫記錄的計算機(jī)程序來說,如果需要先釋放高編號的記錄才能訪問新的記錄,那么運(yùn)行效率就不會高,因此這種方法在這里并不實用。
Chandy/Misra解法
1984年,K. Mani Chandy和J. Misra提出了哲學(xué)家就餐問題的另一個解法,允許任意的用戶(編號{displaystyle P_{1},cdots ,P_{n}}
)爭用任意數(shù)量的資源。與資源分級解法不同的是,這里編號可以是任意的。
把餐叉湊成對,讓要吃的人先吃,沒餐叉的人得到一張換餐叉券。
餓了,把換餐叉券交給有餐叉的人,有餐叉的人吃飽了會把餐叉交給有券的人。有了券的人不會再得到第二張券。
保證有餐叉的都有得吃。
這個解法允許很大的并行性,適用于任意大的問題。
總結(jié)
以上是生活随笔為你收集整理的php 哲学家进餐,IPC问题-哲学家就餐(示例代码)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在无痛人流多少钱啊?
- 下一篇: 满天星的花语和祝福语