1. 程式人生 > >死鎖的產生及處理策略條件

死鎖的產生及處理策略條件

死鎖

什麼是死鎖?

我們先從互斥量造成的死鎖說起。

當一個執行緒去申請一個已經被持有,但是還沒有釋放的互斥量時,執行緒將會被阻塞,直到該互斥量被釋放。如果該互斥量不被釋放,該執行緒將會被一直阻塞。

因次,基於以上的原因,我們可以認為當一個執行緒去申請一個永遠不會被釋放的互斥量時,該執行緒將會被永遠阻塞,這種情景我們稱之為死鎖。更寬泛的說,死鎖就是,一個執行緒阻塞的等待一個永遠不會為真的條件

以下為兩個常見的互斥量中死鎖場景

(1)當一個執行緒重複的拿取同一個互斥量

當一個執行緒申請到該互斥量後,在持有該互斥量的同時,再次申請該互斥量。而此時,因為該互斥量已經被它自身持有,再次申請時,該執行緒將會被阻塞。但是改互斥量必須被被它自身釋放後,才能繼續被申請。但此時,執行緒被阻塞,將永遠無法釋放鎖,並再次申請。所以該執行緒將會被永遠阻塞。這種場景會出現在,在一個函式的內部存在對鎖的申請,當一個執行緒呼叫該函式申請到鎖後,在鎖的內部再次呼叫該函式,就會出現該執行緒對一個互斥量同時申請兩次。

在這裡插入圖片描述
(2)當兩個執行緒,對兩個互斥量以相反的順序進行相互持有

假如有兩個執行緒 A B ,有兩個 互斥量 1 和 2,執行緒A先申請2鎖 ,執行緒B先申請1鎖,當執行緒A申請完2 後,在持有2的同時去申請1,當執行緒B申請完1後,在持有1的同時去申請2.但是此時,雙方都去申請對方的鎖,但是鎖被對方持有,所以兩個執行緒只能阻塞等待,在陷入阻塞後,雙方持有的鎖都將無法釋放,所以兩個執行緒將會永遠的阻塞。從而造成死鎖。

在這裡插入圖片描述

以上兩種場景是在互斥量的條件下,常見的死鎖場景,但是這兩種造成死鎖的場景,並不侷限於互斥量,只要滿足產生死鎖的條件,就會出現死鎖。

前人總結了產生了死鎖的四個必要條件:

  • 互斥條件。

與鎖一樣,要麼能被申請,要麼就只能等待。在任意時刻,某份資源只能被一個程序或執行緒使用。

  • 佔有和等待條件。

是指某個執行緒或程序,在佔有某份資源後還可以申請其他的資源。

  • 不可搶佔條件。

當某份資源被某一程序或執行緒佔有時,不能被其他執行緒或程序強制性的搶佔,只能被佔有它的執行緒主動的釋放。

  • 環路等待條件。

死鎖發生時,系統中一定有兩個或兩個以上的程序組成的一條環路,該環路中的每一個執行緒或程序都在等待下一個程序所佔用的資源。

以上的四個條件必須同時滿足,才會可能造成死鎖。只要有一個條件不滿足,就不會造成死鎖。

死鎖的產生並不僅會只有互斥量時會發生,只要滿足以上四個條件即可。在系統中,有許多隻能被互斥性訪問的獨佔資源,如請求獨佔性的io裝置,印表機等,在對其進行操作時,也有可能造成死鎖。

處理死鎖的四種策略

(1)忽略該問題。

把死鎖忽略,不注意死鎖。有的死鎖產生的時間並不確定。而且死鎖發生的頻度,造成問題的嚴重性不同。假如對於一個死鎖每隔幾個月或者每個幾年出現一次,而且每次造成的問題並不嚴重,那麼此時,工程師可能並不會以損失可用性或效能損失的代價去防止死鎖。此種情況下就屬於忽略死鎖的問題。

(2)檢測死鎖並恢復。

當出現死鎖時,通過檢測死鎖的技術,檢測到出現的死鎖,對於找到的死鎖進行恢復。

(3)仔細對資源分配,動態的避免死鎖。
(4)通過破壞引起死鎖的四個必要條件之一,以此來避免死鎖。