系統爲什麼會死鎖?

注:本文主要參考<<現代操作系統>>6.1,6.2節

何爲死鎖

先給大家講一個關於死鎖的笑話:
某天張三去面試,面試官問他你知道什麼是死鎖嗎?張三說:你先給我offer我就告訴你.面試官說你先告訴我,我再給你offer.張三說:不行,你先給我offer,我再高速你.面試官說:不行,你先告訴我,我再給你offer.於是這場面試持續進行…
哈哈哈!

在計算機系統中,某些資源在同一時刻最多隻能被一個進程使用,例如打印機.如果兩個進程在同一時刻使用打印機,那打印出的一份文檔上可能交叉打印出兩個進程準備打印的內容,這顯然會造成混亂.因此操作系統必須提高某種解決方案保證這類資源的排他性訪問.操作系統可能使用類似互斥量的方式保存打印機在任一時刻最多被一個進程使用.

通過實現一些必要資源的排他性訪問,我們避免了多個進程同時獲取該資源可能造成的混亂,但同時也爲其他問題埋下了隱患,這便是死鎖.考慮如下問題,兩個進程需要完成相同的工作,將掃描後的文檔刻錄到CD上.操作系統能夠確保掃描儀和CD刻錄機的排他性訪問.假設某一時刻進程A獲取到了掃描儀的訪問權,進程B獲取到了CD刻錄機的訪問權,此時進程A需要獲取刻錄機時會失敗,因此刻錄機正被進程B佔用.而進程B準備獲取掃描儀時也會失敗,因此其正被進程A佔用.由於進程A在無法獲取CD刻錄機的情況下被阻塞,進程B也因無法獲取掃描儀而被阻塞.此時兩個進程無法釋放已佔用的資源,導致互不相讓,因而引發死鎖.

在上例中,我們訪問的資源由操作系統提供了排他性訪問,在一些情形下,程序員可能訪問由自己添加了排他性條件的資源,例如在生產者-消費者問題中,我們通過添加互斥量保證同一時刻進程一個能夠訪問緩衝區中的內容.在此情形下,多個進程間也有可能引發死鎖.

死鎖的規範定義如下:

如果一個進程集合中的每個進程都在等待只能由該進程集合中的其他進程才能引發的事件,那麼,該進程集合就是死鎖的。

由於所有的進程都在等待,所以沒有一個進程能引發可以喚醒該進程集合中的其他進程的事件,這樣,所有的進程都只好無限期等待下去。在這一模型中,我們假設進程只含有一個線程,並且被阻塞的進程無法由中斷喚醒,無中斷條件使死鎖的進程不能被時鐘中斷等喚醒,從而不能引發釋放該集合中的其他進程的事件。

死鎖的必要條件

Coffman等人(1971)總結了發生(資源)死鎖的四個必要條件:

1)互斥條件。每個資源要麼已經分配給了一個進程,要麼就是可用的。
(在前例中,掃描儀與CD刻錄機均是排他性訪問的)

2)佔有和等待條件。已經得到了某個資源的進程可以再請求新的資源。
(在前例中,進程A在獲得掃描儀的訪問權後,還可以繼續請求CD刻錄機,同樣,進程B在獲得刻錄機的權限後,還可以請求掃描儀)

3)不可搶佔條件。已經分配給一個進程的資源不能強制性地被搶佔,它只能被佔有它的進程顯式地釋放。
(在前例中,進程A獲得的掃描儀無法被其他進程搶佔,只能在進程A結束使用後主動釋放)

4)環路等待條件。死鎖發生時,系統中一定有由兩個或兩個以上的進程組成的一條環路,該環路中的每個進程都在等待着下一個進程所佔有的資源。
(進程A與進程B構成一條環路)

死鎖發生時,以上四個條件一定是同時滿足的。如果其中任何一個條件不成立,死鎖就不會發生。因此,我們可以通過何時的方式破壞其中的某些條件從而避免死鎖.

使用資源分配圖進行死鎖建模

Holt(1972)指出如何用有向圖建立上述四個條件的模型。在有向圖中有兩類節點:用圓形表示的進程,用方形表示的資源。從資源節點到進程節點的有向邊代表該資源已被請求、授權並被進程佔用。如果資源分配圖中存在一條環形路徑,則表明發生死鎖.

在下圖中,有A,B,C三個進程,R,S,T三個資源.若進程調度執行順序如左側文本框中所示,則會構成死鎖.
死鎖圖例

死鎖問題解決方案

有四種處理死鎖的策略:

1)忽略該問題。也許如果你忽略它,它也會忽略你。

2)檢測死鎖並恢復。讓死鎖發生,檢測它們是否發生,一旦發生死鎖,採取行動解決問題。

3)仔細對資源進行分配,動態地避免死鎖。

4)通過破壞引起死鎖的四個必要條件之一,防止死鎖的產生。

下一篇中我們逐一分析死鎖的四種解決方案.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章