一、死鎖的概念:
1、死鎖的現象描述:
在很多應用中,需要一個進程排他性的訪問若干種資源而不是一種。例如,兩個進程准備分別將掃描的文檔記錄到CD上。進程A請求使用掃描儀,
並被授權使用。但進程B首先請求CD刻錄機,也被授權使用。這時,A請求使用CD刻錄機,但這個請求在B釋放CD刻錄機前會被拒絕。但是,進程B非但
不會釋放CD刻錄機,還去請求掃描儀。這時,兩個進程僵持不下,都被阻塞,並一直處於這樣的狀態。這種狀況就叫做死鎖(deadlock)。
2、死鎖的規范定義:
如果一個進程集合中的每個進程都在等待只能由該進程集合中的其他進程才能引發的事件,那么,該進程集合是死鎖的。
二、產生死鎖的四個必要條件:
1、互斥條件。每個資源要么意境分配給了一個進程,要么就是可用的。
2、占有和等待條件。已經得到可某個資源的進程可以在請求新的資源。
3、不可搶占條件。已經分配給一個進程的資源不能強制性地被搶占,它只能占有它的進程顯式的釋放。
4、循環等待條件。死鎖發生時,系統中一定有兩個或兩個以上的進程組成的一條環路,該環路中的每一個進程都在等待着下一個進程所占有的資源。
死鎖發生時,以上四個條件一定是同時滿足的。如果有任意一條不成立,那么死鎖就不會發生。
三、如何有效地預防死鎖
預防死鎖的根本辦法就是要使死鎖產生的4個必要條件之一不存在。下面來分析一下破壞這些條件的可能性。
1、破壞互斥條件
破壞互斥條件即允許多個進程同時訪問資源。由於多數資源的必須互斥訪問這一固有特性不能改變,因此,死鎖的預防通過破壞這個必要條件實現在
很多場合是行不通的。例如,打印機資源必須互斥使用,否則幾個進程同時使用,每個進程各打印一行,這種輸出信息的方式顯然是不能被用戶接受的。
2、破壞占有和等待條件
采用資源靜態分配法可破壞這一條件,該方法是指在進程運行前,一次性地_請分配它運行所需的全部資源。若系統有足夠的資源分配給某一進程,則
一次性地將其所需資源分配給該進程,這樣,在進程運行期間便不會再提出任何資源請求,從而使等待條件不成立。如果分配時有一種資源要求不能滿足,
則進程需要的其他資源也先不分配給進程,從而避免進程在等待期間占用任何資源,破壞了占用條件,從而避免死鎖的發生。
優缺點:該方法控制簡單且容易實現,但由於進程運行期間對所需資源的全部占用,使得某些使用時間很短的資源被長時間占用,這樣會嚴重影響系統
資源的充分利用,導致資源利用率降低,同吋也影響到未獲得全部資源的進程推遲運行。
3、破壞不剝奪條件
采用剝奪式控制方法可以破壞該條件,該方法是使一個已保持了某些資源的進程,由於新的資源要求目前得不到滿足,它必須先暫時釋放巳保持的所有資
源(一種剝奪式),然后去等待,以后再一起向系統提出巾請,這樣也能防止死鎖。
優缺點:這種方法實現起來相對較難,為了保護進程自動放棄資源的現場以及后來的再次恢復,需要付出高昂的代價,並且這種方法只適用於處理機和存
儲器資源,對其他資源,此法不宜使用。
4、破壞循環等待條件
采用資源順序分配法可破壞該條件。這種分配方法的基本思想是:把系統的全部資源分成多個層次,一個進程得到某一層的一個資源后,它只能再_請較
高一層的資源;當一個進程要釋放某層的一個資源時,必須先釋放所占有的較高層的資源;當一個進程獲得了某一層的一個資源后,它想再申請該層中的另一個
資源,就必須先釋放在該層中巳占有的資源。或者說,進程釋放資源的順序是按照中請資源的相反順序進行的。這樣可以預防循環等待現象的發生,因此不會
發生死鎖。使用該方法要特別注意的問題是對資源所處層次的安排。在通常情況下,把各進程經常用到的、比較普遍的資源安排在較低的層次上,把重要且相
對匱乏的資源安排在較高的層次上,以便實現對各資源的最大限度的利用。
優缺點:該方法相對於前面介紹的方法,在資源利用率和系統吞吐量上都有明顯的改善。但也存在一些缺陷:
(1)低層次的資源必須在進程請求分配髙層次的資源之前提前申請,這對於暫時不需使用的低層次資源來說,會因空閑等待而產生浪費。
(2)各類設備的資源層次一經設定,便不能經常隨意改動,這就限制了新類型設備的增加。
(3)各資源的層次是按照大多數進程使用資源的順序設置的。對於資源使用與此層次相閃配的進程,資源能得到有效的利用,否則,資源的浪費現象將
仍然存在。
四、如何解除死鎖
死鎖的解除實質上就是如何讓釋放資源的進程能夠繼續運行.
為了解除死鎖就要剝奪資源,此時,需要考慮一下幾個問題:
(1) 選擇一個犧牲進程,即要剝奪哪個進程的哪些資源
(2) 重新運行或回到某一點開始繼續運行.若從一個進程那里剝奪了資源,要為該進程作些什么事情?顯然,這個進程是不能繼續正常執行了.必須將該進程
回到七點或某個狀態,以后在重新開始執行.令進程夭折的方法雖然簡單,但代價大;而更有效的方法是只讓它退回到足以解除死鎖的地步即可.那么,問題轉換成進
程回退的狀態由什么組成?怎樣才能更方便的確定該狀態,這就要求系統保持根多的有關進程運行的信息.
(3) 怎樣保證不發生”餓死”現象,即如何保證並不總是剝奪同一進程的資源,而導致該進程處於”飢餓”狀態.
(4) “最小代價”,即最經濟合算的算法,使得進程回退帶來的開銷最小.但是,”最小開銷”是很不精確的,進程重新運行的開銷包括很多因素
(a) 進程的優先級
(b) 進程已經運行了多長時間了,該浸沉完成其任務還需要多長時間
(c) 該進程使用的資源種類和數量?這些資源能簡單的剝奪嗎?
(d) 為完成任務,進程還需要多少資源?
(e) 有多少進程要被撤銷
(f) 該進程被重新啟動運行的次數.
一旦決定一個進程必須回退,就一定要確定這個進程回退多少.最簡單的方法是從頭來,讓其重新運行,這將會使一個進程的工作”前功盡棄”.
死鎖解除法可歸納為兩大類
- 剝奪資源
使用掛起/激活機制掛起一些進程,剝奪它們占有的資源給死鎖進程,以解除死鎖,待以后條件滿足時,在激活被掛起的進程.
由於死鎖是由進程競爭資源而引起的,所以,可以從一些進程那里強行剝奪足夠數量的資源分配給死鎖進程,以解除死鎖狀態.剝奪的順序可以是以話費
最小資源數為依據.每次剝奪后,需要再次調用死鎖檢測算法,資源被剝奪的進程為了在得到該資源,必須重新提出申請,為了安全的釋放資源,該進程就必須
返回到分配資源前的某一點.金昌使用的方法有:
(1) 歡迎算法,即恢復計算結果和狀態.
(2) 建立檢查點主要是用來恢復分配前的狀態.這種發放對實時系統和長時間運行的數據處理來說是一種常用技術.在實時系統中,經常在某些程序地址插
入檢 查的程序段,即采用檢查點的技術來驗證系統的正確性,如發現故障,可從檢查點重新啟動.因此,在有些實時系統中,一旦發現死鎖,可以在釋放某進程的資
源后,從檢查點重新啟動.
2.撤銷進程
撤銷死鎖進程.將它們占有的資源分配給另一些死鎖進程,知道死鎖解除為止.
可以撤銷所有死鎖進程,或者琢個撤銷死鎖進程,美撤銷一個進程就檢測死鎖是否繼續存在,若已沒有死鎖,就停止進程的撤銷.
如果按照某種順序依次撤銷已死鎖的進程,知道獲得為解除死鎖所需要的足夠可用的資源為止,那么在極端情況下,這種發放可能造成除一個死鎖進程外,
其余的死鎖進程全部被撤銷的局面.
按照什么原則撤銷進程?較實用而又簡單的方法是撤銷那些代價最小的進程,或者使撤銷進程的數目最小.一下幾點可作為衡量撤銷代價的標准:
(1) 進程優先數,即被撤銷進程的優先數.
(2) 進程類的外部代價.不同類型的進程可以規定出各自的撤銷代價.系統可根據這些規定,撤銷代價最小的進程,達到解除死鎖的目的.
(3) 運行代價,即重新啟動進程並運行到當前撤銷點所需要的代價.這一點可由系統記帳程序給出
優缺點:撤銷發的優點是簡單明了,但有時可能不分青紅皂白的撤銷一些甚至不影響死鎖的進程
