Linux 什麼是死鎖以及如何避免死鎖

2021-08-19 05:56:59 字數 2937 閱讀 1431

介紹死鎖之前,先來說一下作業系統中的資源分類

按照使用次數分類

(1)可重用性資源

每乙個可重用資源中的單元只能分配給乙個程序使用,不允許多個執行緒共享。

程序使用資源順序:

(1) 請求資源,如果請求失敗程序阻塞或迴圈等待;

(2) 使用資源;

(3)釋放資源。

系統中的可重用資源數目都是相對固定的程式執行時不能增加或刪除。

(2)消耗性資源

它是臨時資源,由程序執行動態建立和消耗的,每一類消耗性資源單元數目都是不斷變化的,通常在生產者執行緒中建立,在消費者執行緒中消耗。

按照能否搶占分類

(1)可搶占資源

cpu,主存等可以共享的資源。

(2)不可搶占資源

印表機,光碟機等不可共享的資源。

定義

執行緒死鎖是指由於兩個或者多個執行緒互相持有對方所需要的資源,導致這些執行緒處於等待狀態,無法前往執行。

當執行緒進入物件的synchronized**塊時,便占有了資源,直到它退出該**塊或者呼叫wait方法,才釋放資源,在此期間,其他執行緒將不能進入該**塊。

當執行緒互相持有對方所需要的資源時,會互相等待對方釋放資源,如果執行緒都不主動釋放所占有的資源,將產生死鎖。

產生死鎖的情境

(1)競爭不可搶占資源引起的死鎖

打個比方,假設有p1和p2兩個程序,都需要a和b兩個資源,現在p1持有a等待b資源,而p2持有b等待a資源,兩個都等待另乙個資源而不肯釋放資源,就這樣無限等待中,這就形成死鎖,這也是死鎖的一種情況。給死鎖下個定義,如果一組程序中每乙個程序都在等待僅由該組程序中的其他程序才能引發的事件,那麼該組程序是死鎖的。

(2)競爭可消耗資源引起的死鎖

有p1,p2,p3三個程序,p1向p2傳送訊息並接受p3傳送的訊息,p2向p3傳送訊息並接受p2的訊息,p3向p1傳送訊息並接受p2的訊息,如果設定是先接到訊息後傳送訊息,則所有的訊息都不能傳送,這就造成死鎖。

(3)執行緒執行順序不當引起的死鎖

有程序p1,p2,都需要資源a,b,本來可以p1執行a –> p1執行b –> p2執行a –> p2執行b,但是順序換了,p1執行a時p2執行b,容易發生第一種死鎖。互相搶占資源。

(4)死鎖的另一種:遞迴死鎖

所謂遞迴函式就是自呼叫函式,在函式體內直接或間接的呼叫自己,即函式的巢狀是函式本身。

遞迴方式有兩種:直接遞迴和間接遞迴,直接遞迴就是在函式中出現呼叫函式本身。間接遞迴,指函式中呼叫了其他函式,而該其他函式又呼叫了本函式。

那什麼時候使用遞迴呢?一般來說當你要在某段**邏輯中使用迴圈迭代的時候但是迭代的次數在迭代之前無法知曉的情況下使用遞迴。

打個比方你要在乙個資料夾中查詢某個檔案,而這個資料夾底下有n多子資料夾和檔案,當你在不知道有多少層資料夾和檔案的情況下你就得用到遞迴了。

遞迴的優點就是讓**顯得很簡潔,同時有些應用場景不得不使用遞迴比如前面說的找檔案。

遞迴是個好東西但是在某些時候也會給你帶來一些麻煩。比如在多執行緒的環境下使用遞迴,遇到了多執行緒那麼就不得不面對同步的問題。

而遞迴程式遇到同步的時候很容易出問題。多執行緒的遞迴就是指遞迴鏈中的某個方法由另外乙個執行緒來操作。(如果是在乙個執行緒中就不存在死鎖問題)

下面來總結一下產生死鎖的四個必要條件

1.互斥條件

程序對於所分配到的資源具有排它性,即乙個資源只能被乙個程序占用,直到被該程序釋放

2.請求和保持條件

乙個程序因請求被占用資源而發生阻塞時,對已獲得的資源保持不放。

3.不剝奪條件

任何乙個資源在沒被該程序釋放之前,任何其他程序都無法對他剝奪占用

4.迴圈等待條件

當發生死鎖時,所等待的程序必定會形成乙個環路(類似於死迴圈),造成永久阻塞。

下面來說明一下如何避免死鎖的產生

1、預防死鎖

上面介紹了死鎖產生的四個必要條件,那如何避免死鎖的產生呢?只要破壞上面四個必要條件其中之一,就不會發生死鎖。

2、避免死鎖

在資源的動態分配過程中,用某種方法防止系統進入不安全狀態,從而避免死鎖。

預防死鎖和避免死鎖都屬於事先預防策略,但預防死鎖的限制條件比較嚴格,實現起來 較為簡單,但往往導致系統的效率低,資源利用率低;

避免死鎖的限制條件相對寬鬆,資源 分配後需要通過演算法來判斷是否進入不安全狀態,實現起來較為複雜。

3、死鎖的檢測

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

4、解除死鎖

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

什麼是死鎖,以及如何預防

所謂死鎖 是指兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。由於資源占用是互斥的,當某個程序提出申請資源後,使得有關程序在無外力協助下,永遠分配不到必需的資源而...

什麼是死鎖?如何避免死鎖? 以及實現執行緒死鎖才程式

所謂死鎖 是指兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。由於資源占用是互斥的,當某個程序提出申請資源後,使得有關程序在無外力協助下,永遠分配不到必需的資源而...

什麼是死鎖?如何避免死鎖?

所謂死鎖 是指兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖程序。由於資源占用是互斥的,當某個程序提出申請資源後,使得有關程序在無外力協助下,永遠分配不到必需的資源而...