在Linux下線程死鎖的四個條件

 一、死鎖的原因和必要條件

1.死鎖的概念

 一般情況下,如果同一個線程先後兩次調用lock,在第一次調用時,由於鎖已經被佔,該線程會掛起等待別的線程釋放鎖,然而鎖正是被自己佔着的,該線程又被掛起,沒有機會釋放鎖,因此,就永遠處於掛起等待狀態了,這叫做死鎖(Deadlock)。另種典型的死鎖情形是這樣:線程A獲 得了鎖1,線程B獲得了鎖2,這時線程A調用lock試圖獲得鎖2,結果是需要掛起等待線程B釋放鎖2,而這時線程B也調用lock試圖獲得鎖1,結果是需要掛起等待線程A釋放鎖1,於是線程A和B都永遠處於掛起狀態了。

      所謂死鎖,是指多個線程在運行過程中因爭奪資源而造成的一種僵局(DeadlyEmbreace)即互相等待的現象,當線程處於這種僵持狀態時,若無外力作用,它們都將無法向前推進。

2.產生死鎖的原因

(1).競爭資源。當系統中供多個線程共享的資源如打印機,公用隊列等,其數目不足以滿足諸線程的需要的時候,會引起諸線程對資源的競爭而產生死鎖。

(2).線程間推進順序非法。線程在運行過程中,請求和釋放資源的順序不當,也同樣會導致產生線程死鎖。

下面詳細分析產生死鎖的原因:

(1)競爭資源引起死鎖

1)可剝奪性和非剝奪性資源

      可把系統的資源分成兩類,一類是可剝奪性資源,是指某線程在獲得這類資源後,該線程可以再被其它線程或系統剝奪。如優先級高的線程可以剝奪優先級低的線程的資源。又如線程間的切換。另一類是非剝奪性資源,當系統把這類資源分配給某個線程後,再不能強行收回,只能在其用完後自行釋放,如磁帶機、打印機等。

2).競爭非剝奪性資源

       在系統所配置的非剝奪性資源,由於它們的數量不能滿足諸線程的需要,會使線程在運行過程中,因爭奪這些資源陷入僵局。

3).競爭臨時性資源

      打印機資源屬於可順序重複使用型資源,稱爲永久性資源。所謂的臨時性資源,是指被線程使用一短暫時間後便無用的資源,故也稱之爲消耗性資源,它也可能引起死鎖。

(2).線程推進順序不當引起死鎖

     如開始所提線程A獲 得了鎖1,線程B獲得了鎖2,這時線程A調用lock試圖獲得鎖2,結果是需要掛起等待線程B釋放鎖2,這時線程B也調用lock試圖獲得鎖1,結果是需要掛起等待線程A釋放鎖1,於是線程A和B都將永遠處於掛起狀態了。

3.產生死鎖的必要條件

     雖然線程在運行過程中可能發生死鎖,但死鎖的發生也必須具備一定的條件。綜上所述不難看出,死鎖的發生必須具備下列四個必要條件。

(1).互斥條件指線程對所分配的資源進行排它性使用,即在一段時間內某資源只由一個線程佔用。如果此時還有其它線程請求該資源,則請求者只能等待,直至佔有該資源的線程用畢釋放。

(2).請求和保持條件:指線程已經保持了至少一個資源,但又提出了新的資源請求,而該資源又被其它線程佔有,或者已經擁有了該資源卻又再次請求,此時請求線程阻塞,但又對自己已獲得的資源保持不放。

(3).不剝奪條件:指線程在已獲得的資源,在未使用完之前,不能被剝奪,只能在使用完時由自己釋放。

(4).環路等待條件:指在發生死鎖時,必然存在一個線程--資源的環形鏈,即線程集合{P0,P1,P2,P3,...Pn}中的P0正在等待P1佔用的資源;P1正在等待P2佔用的資源,......,Pn正在等待已被P0佔用的資源。

4.處理死鎖的基本方法

     爲保證系統中諸線程的正常運行,應事先採取必要的措施,來預防發生死鎖。在系統中已經出現死鎖後,則應及時檢測到思索的發生,並應採取適當的措施來解除死鎖。目前,處理死鎖的方法可歸結爲以下四種:

(1).預防死鎖。這是一種較簡單和直觀的方法。該方法是通過設置某些限制條件,去破壞產生死鎖的四個必要條件中的一個或幾個,來預防發生死鎖。但由於所施加的限制條件往往太嚴格,因而會導致系統資源利用率和系統吞吐量低。

(2).避免死鎖。該方法同樣是屬於事先預防的策略,但它並不須事先採取各種限制措施去破壞產生死鎖的四個必要條件,而是在資源的動態分配過程中,用某種方法去防止系統進入不安全狀態,從而避免發生死鎖。這種方法只需事先施加較弱的限制條件,便可獲得較高的資源利用率及系統吞吐量,但在事實上有一定的難度。目前在較完善的系統中常用此方法來避免發生死鎖。

(3).檢測死鎖。這種方法並不須事先採取任何限制性措施,也不必檢查系統是否已經進入不安全區,而是允許系統在運行過程中發生死鎖。但可通過系統所設置的檢測機構,及時的檢測出死鎖的發生,並精確地確定與死鎖有關的線程和資源;然後採取適當措施,從系統中將已發生的死鎖清除掉。

(4).解除死鎖。這是與檢測死鎖相配套的一種措施。當檢測到系統中已發生死鎖時,須將線程從死鎖狀態中解脫出來。常用的實施方法是撤銷或掛起一些線程,以便回收一些資源,再將這些資源分配給已處於阻塞狀態的線程,是之轉爲就緒狀態,以繼續運行。死鎖的檢測和解除措施有可能使系統獲得較好的資源利用率和吞吐量,但在實現上難度也最大。

二、預防死鎖的方法

  (一)預防死鎖的方法是使四個必要條件中的第2、3、4個條件之一不能成立,來避免發生死鎖。至於必要條件1,因爲它是由設備的固有特性所決定的,不僅不能改變,還應加以保證。

 1.摒棄“請求和保持條件”

在採用這種方法時,系統規定所有線程在開始運行之前,都必須一次性的申請其在整個運行過程中所需的全部資源。

優點:簡單,易於實現且安全

缺點:資源被嚴重浪費,線程運行被延遲

2.摒棄“不剝奪”條件

在採用這種方法時系統規定,線程是逐個提出對資源的要求的。當一個已經保持了某些資源的線程,在提出新的資源請求而不能立即得到滿足時,必須釋放它已經保持了的所有資源,待以後需要時再重新申請。

    這種方法實現起來比較複雜且要付出很大的代價。並且有可能使進程的執行被無限的推遲,而且也增加了系統開銷,降低了系統吞吐量。

3.摒棄”環路等待“條件

   這種方法規定,系統將所有的資源按類型進行線性排隊,並賦予不同的序號。

優點:資源利用率和系統吞吐量都有明顯的改善

缺點:(1)資源的序號必須相對穩定,限制了新類型設備的增加

(2).限制用戶簡單自主的編程。

(3).會對資源造成浪費

(二)系統安全狀態

1.安全狀態

       在避免死鎖的方法中,允許線程動態的申請資源,但系統在進行資源分配之前,應先計算此次分配的安全性。若此次分配不會導致系統進入不安全狀態,則將資源分配給線程,否則令其等待。

    所謂安全狀態,是指系統能按某種線程序列,來爲每個線程分配資源,直至滿足每個線程對資源的最大需求,使每個線程都可順利的完成。如果系統無法找到這樣一個安全序列,則成系統處於不安全狀態。

    雖然並非所有的不安全狀態都必然會轉爲死鎖狀態,但系統進入不安全狀態後就有可能進入死鎖狀態,但只要系統處於安全狀態,系統便可避免進入死鎖狀態。


銀行家算法

 避免死鎖算法中最有代表性的算法是Dijkstra E.W 於1968年提出的銀行家算法

   銀行家算法是避免死鎖的一種重要方法,防止死鎖的機構只能確保上述四個條件之一不出現,則系統就不會發生死鎖。通過這個算法可以用來解決生活中的實際問題,如銀行貸款等。

    程序實現思路銀行家算法顧名思義是來源於銀行的借貸業務,一定數量的本金要應多個客戶的借貸週轉,爲了防止銀行家資金無法週轉而倒閉,對每一筆貸款,必須考察其是否能限期歸還。在操作系統中研究資源分配策略時也有類似問題,系統中有限資源要供多個進程使用,必須保證得到的資源的進程能在有限的時間內歸還資源,以供其他進程使用資源。如果資源分配不得到就會發生進程循環等待資源,則進程都無法繼續執行下去的死鎖現象。

   把一個進程需要和已佔有資源的情況記錄在進程控制中,假定進程控制塊PCB其中“狀態”有就緒態、等待態和完成態。當進程在處於等待態時,表示系統不能滿足該進程當前的資源申請。“資源需求總量”表示進程在整個執行過程中總共要申請的資源量。顯然,每個進程的資源需求總量不能超過系統擁有的資源總數, 銀行家算法進行資源分配可以避免死鎖。

這是講述進程中死鎖的現象,在線程中同樣適用。

三、死鎖的檢測解除

1.死鎖的檢測

(1).系統必須保存有關資源的請求和分配信息

(2).系統必須提供一種算法,以利用這些信息來檢測系統是否已進入死鎖狀態。

2.死鎖的解除

(1).剝奪資源

(2).撤銷線程

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