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