哲學家就餐問題

2022-09-22 07:03:12 字數 1590 閱讀 9471

五個哲學家(a~e)圍著一張圓桌就餐,他們每個人面前都有一盤通心粉。由於通心粉很滑,所以需要兩隻筷子才能夾住,但每兩個盤子之間只放著乙隻筷子,如下圖。

哲學家只有兩個動作:要麼就餐,要麼思考。而且他們之間從不交談。

當乙個哲學家餓了的時候,就拿起盤子左右兩邊的筷子開始就餐(不能同時拿起兩隻筷子)。就餐完以後,就把筷子放回盤子左右,繼續思考。

由於他們之間互不交談,所以很容易出現「死鎖」:假如每個人都拿著左邊的筷子,則所有人都在等右邊的筷子,誰都吃不了。

我們可以規定,拿著乙隻筷子等待另乙隻筷子的時間超過五分鐘就放下手中的筷子,並且再等待五分鐘之後進行下一次嘗試。

這個策略消除了死鎖,不過還是有可能發生「活鎖」:假如這五個人同時拿起左邊的筷子,大家都在等另乙隻筷子,五分鐘之後大家同時放下筷子。再過五分鐘之後又同時拿起左邊的筷子……

在計算機領域中,哲學家就餐問題可以抽象成資源搶占問題,筷子就是「資源」。一種常用的計算機技術就是給資源「加鎖」,乙個資源同時只能供乙個程式或者一段**訪問。當乙個程式要使用的資源被另外乙個程式鎖定的時候,只能等待資源被解鎖。這就容易出現死鎖情況,當有兩個程式需要訪問兩個相同的資源時,如果每個程式都鎖了乙個資源,那麼兩者都在等待對方解鎖另乙個資源的解鎖,最後誰都無法執行。

以下介紹三種解決方案。

就就餐問題,我們可以引入乙個服務生,哲學家要經過服務生同意才能拿筷子,因為服務生知道哪只筷子在使用,他可以阻止死鎖的發生。

這很好理解,只有當盤子左右的筷子都空閒的時候,服務生才會同意哲學家就餐,這樣就不存在有人拿著乙隻筷子在等待另乙隻筷子的情況,也就杜絕了死鎖的發生。

另外一種方法就是給資源分級,例如上圖中的五隻筷子,給它們分級為1~5五個等級。

約定:每位哲學家在就餐拿筷子的時候,只能先拿級別比較低的筷子,然後才能拿級別比較高的。用餐完以後,先放下級別比較高的筷子,再放下編號比較低的。

這樣也不會出現死鎖的情況。

假如大家同時拿起乙隻筷子,那麼級別最高的5號筷子一定還留在桌子上。此時哲學家a或者e就能拿起它湊成兩隻筷子開始進餐。進餐完以後放下筷子,其他哲學家又能進餐了……

這是由k. mani chandy和j. misra提出的又一種解法:

剛開始的時候,把每只筷子都分給編號比較小的哲學家,即有:a~1,b~2,c~3,d~4,e~5。並把筷子都定義為「髒的」。

當某位哲學家要使用筷子的時候,他缺哪只筷子,就向擁有那只筷子的哲學家傳送乙個請求。

當擁有筷子的哲學家收到請求時,如果筷子是髒的,就把筷子擦乾淨並交出去;否則就繼續留著。

當哲學家擁有兩隻乾淨的筷子時就可以就餐了,吃完以後筷子就變成髒的了。如果有哲學家之前請求過其中乙隻筷子,則把筷子擦乾淨並交出去。

示例:起初,先把 5 只筷子分別分給 a~e 五位哲學家,並定義為臟的。

假設b想要吃東西了,他把手裡的2號筷子擦乾淨,可是還缺1號筷子呀,於是就向擁有1號筷子的a傳送乙個請求。

a收到請求,因為此時1號筷子是髒的,所以a得把1號筷子擦乾淨,並交給b。

b有兩隻筷子了,準備開吃了。可就在此時,c也想吃東西了,向b傳送過來乙個請求,想要2號筷子。

b手裡的2號筷子是乾淨的呀,於是b先吃自己的,吃完以後2號筷子變成髒的了,b再把筷子擦乾淨並交給c。

…………

…………

哲學家就餐問題

本文是哲學家就餐問題在 linux 上的程式實現,與windows 平台的實現類似,程式上稍有不同。philosopherdining.cpp include include include include include include rasutil.h using namespace std ...

哲學家就餐問題

pragma once include include include include include include include include include include include include include stdafx.h handle chopstick 5 room l...

哲學家就餐問題

假設有五位哲學家圍坐在一張圓形餐桌旁,做以下兩件事情之一 吃飯,或者思考。吃東西的時候,他們就停止思考,思考的時候也停止吃東西。餐桌中間有一大碗義大利面,每兩個哲學家之間有乙隻餐叉。因為用乙隻餐叉很難吃到義大利面,所以假設哲學家必須用兩隻餐叉吃東西。他們只能使用自己左右手邊的那兩隻餐叉。哲學家就餐問...