Linux死鎖學習(下)

2021-08-19 09:41:59 字數 4015 閱讀 9048

傳說中鴕鳥看到危險就把頭埋在地底下。當你對某一件事情沒有乙個很好的解決方法時,那就忽略它,就像鴕鳥面對危險時會把它深埋在沙礫中,裝作看不到。這樣的演算法稱為「鴕鳥演算法「。

在針對死鎖問題時:鴕鳥演算法就是忽略死鎖,不去處理死鎖

鴕鳥演算法可以稱之為不是辦法的辦法。在電腦科學中,鴕鳥演算法是解決潛在問題的一種方法。假設的前提是,這樣的問題出現的概率很低。在作業系統中,為應對死鎖問題,可以採用這樣的一種辦法。如果死鎖很長時間才發生一次,而系統每週都會因硬體故障、編譯器錯誤或作業系統錯誤而崩潰一次,那麼大多數工程師不會以效能損失或者易用性損失的代價來消除死鎖。大多數作業系統,包括unix,minux和windows,處理死鎖問題的辦法僅僅是忽略它。其假設前提是大多數使用者寧可在極偶然的情況下發生死鎖也不願接受效能的損失。因為解決死鎖的問題,通常代價很大。所以鴕鳥演算法,是平衡效能和複雜性而選擇的一種方法。

為了讓這一對比更具體,考慮如下作業系統:當乙個open系統呼叫因物理裝置(例如藍光驅動器或者印表機)忙而得不到回應的時候,作業系統就會阻塞呼叫該系統呼叫的程序。通常是由裝置驅動來決定該採取何種措施。

顯然,阻塞或者返回乙個錯誤**是兩種選擇。如果乙個程序成功的開啟了藍光驅動器,而另乙個程序成功的開啟了印表機,這是每個程序都會試圖開啟另乙個裝置,系統會阻塞這種嘗試,從而發生死鎖。現有系統很少能夠檢測到這種死鎖。

如果在計算機系統中同時具備下面四個必要條件時,那麼會發生死鎖。換句話說,只要下面四個條件有乙個不具備,系統就不會出現死鎖。

前面介紹了死鎖發生時的四個必要條件,只要破壞這四個必要條件中的任意乙個條件,死鎖就不會發生。這就為我們解決死鎖問題提供了可能。一般地,解決死鎖的方法分為死鎖的預防,避免,檢測與恢復三種(注意:死鎖的檢測與恢復是乙個方法)。我們將在下面分別加以介紹。

死鎖的預防是保證系統不進入死鎖狀態的一種策略。它的基本思想是要求程序申請資源時遵循某種協議,從而打破產生死鎖的四個必要條件中的乙個或幾個,保證系統不會進入死鎖狀態。

〈1〉打破互斥條件。即允許程序同時訪問某些資源。但是,有的資源是不允許被同時訪問的,像印表機等等,這是由資源本身的屬性所決定的。所以,這種辦法並無實用價值。

〈2〉打破不可搶占條件。即允許程序強行從佔有者那裡奪取某些資源。就是說,當乙個程序已占有了某些資源,它又申請新的資源,但不能立即被滿足時,它必須釋放所占有的全部資源,以後再重新申請。它所釋放的資源可以分配給其它程序。這就相當於該程序占有的資源被隱蔽地強佔了。這種預防死鎖的方法實現起來困難,會降低系統效能。

〈3〉打破占有且申請條件。可以實行資源預先分配策略。即程序在執行前一次性地向系統申請它所需要的全部資源。如果某個程序所需的全部資源得不到滿足,則不分配任何資源,此程序暫不執行。只有當系統能夠滿足當前程序的全部資源需求時,才一次性地將所申請的資源全部分配給該程序。由於執行的程序已占有了它所需的全部資源,所以不會發生占有資源又申請資源的現象,因此不會發生死鎖。但是,這種策略也有如下缺點

(1)在許多情況下,乙個程序在執行之前不可能知道它所需要的全部資源。這是由於程序在執行時是動態的,不可**的;

(2)資源利用率低。無論所分資源何時用到,乙個程序只有在占有所需的全部資源後才能執行。即使有些資源最後才被該程序用到一次,但該程序在生存期間卻一直占有它們,造成長期佔著不用的狀況。這顯然是一種極大的資源浪費;

(3)降低了程序的併發性。因為資源有限,又加上存在浪費,能分配到所需全部資源的程序個數就必然少了。

(4)打破迴圈等待條件,實行資源有序分配策略。採用這種策略,即把資源事先分類編號,按號分配,使程序在申請,占用資源時不會形成環路。所有程序對資源的請求必須嚴格按資源序號遞增的順序提出。程序占用了小號資源,才能申請大號資源,就不會產生環路,從而預防了死鎖。這種策略與前面的策略相比,資源的利用率和系統吞吐量都有很大提高,但是也存在以下缺點:

死鎖預防方法彙總條件

處理方式

互斥一切使用假離線技術

占有和等待

在開始就請求全部資源

不可搶占

搶占資源

環路等待

對資源進行編號

上面我們講到的死鎖預防是排除死鎖的靜態策略,它使產生死鎖的四個必要條件不能同時具備,從而對程序申請資源的活動加以限制,以保證死鎖不會發生。下面我們介紹排除死鎖的動態策略–死鎖的避免,它不限制程序有關申請資源的命令,而是對程序所發出的每乙個申請資源命令加以動態地檢查,並根據檢查結果決定是否進行資源分配。就是說,在資源分配過程中若**有發生死鎖的可能性,則加以避免。這種方法的關鍵是確定資源分配的安全性。

1.安全序列

我們首先引入安全序列的定義:所謂系統是安全的,是指系統中的所有程序能夠按照某一種次序分配資源,並且依次地執行完畢,這種程序序列就是安全序列。如果存在這樣乙個安全序列,則系統是安全的;如果系統不存在這樣乙個安全序列,則系統是不安全的。

安全序列是這樣組成的:若對於每乙個程序pi,它需要的附加資源可以被系統中當前可用資源加上所有程序pj當前占有資源之和所滿足,則為乙個安全序列,這時系統處於安全狀態,不會進入死鎖狀態。  

雖然存在安全序列時一定不會有死鎖發生,但是系統進入不安全狀態(四個死鎖的必要條件同時發生)也未必會產生死鎖。當然,產生死鎖後,系統一定處於不安全狀態。

2.銀行家演算法

這是乙個著名的避免死鎖的演算法,是由dijstra首先提出來並加以解決的。 

[背景知識]

乙個銀行家如何將一定數目的資金安全地借給若干個客戶,使這些客戶既能借到錢完成要幹的事,同時銀行家又能收回全部資金而不至於破產,這就是銀行家問題。這個問題同作業系統中資源分配問題十分相似:銀行家就像乙個作業系統,客戶就像執行的程序,銀行家的資金就是系統的資源。

[問題的描述]

乙個銀行家擁有一定數量的資金,有若干個客戶要貸款。每個客戶須在一開始就宣告他所需貸款的總額。若該客戶貸款總額不超過銀行家的資金總數,銀行家可以接收客戶的要求。客戶貸款是以每次乙個資金單位(如1萬rmb等)的方式進行的,客戶在借滿所需的全部單位款額之前可能會等待,但銀行家須保證這種等待是有限的,可完成的。

銀行家演算法是從當前狀態出發,逐個按安全序列檢查各客戶誰能完成其工作,然後假定其完成工作且歸還全部貸款,再進而檢查下乙個能完成工作的客戶,……。如果所有客戶都能完成工作,則找到乙個安全序列,銀行家才是安全的。

從上面分析看出,銀行家演算法允許死鎖必要條件中的互斥條件,占有且申請條件,不可搶占條件的存在,這樣,它與預防死鎖的幾種方法相比較,限制條件少了,資源利用程度提高了。

這是該演算法的優點。其缺點是:

〈1〉這個演算法要求客戶數保持固定不變,這在多道程式系統中是難以做到的。

〈2〉這個演算法保證所有客戶在有限的時間內得到滿足,但實時客戶要求快速響應,所以要考慮這個因素。

〈3〉由於要尋找乙個安全序列,實際上增加了系統的開銷。

一般來說,由於作業系統有併發,共享以及隨機性等特點,通過預防和避免的手段達到排除死鎖的目的是很困難的。這需要較大的系統開銷,而且不能充分利用資源。為此,一種簡便的方法是系統為程序分配資源時,不採取任何限制性措施,但是提供了檢測和解脫死鎖的手段:能發現死鎖並從死鎖狀態中恢復出來。因此,在

實際的作業系統中往往採用死鎖的檢測與恢復方法來排除死鎖。

死鎖檢測與恢復是指系統設有專門的機構,當死鎖發生時,該機構能夠檢測到死鎖發生的位置和原因,並能通過外力破壞死鎖發生的必要條件,從而使得併發程序從死鎖狀態中恢復出來。

.死鎖的恢復

一旦在死鎖檢測時發現了死鎖,就要消除死鎖,使系統從死鎖狀態中恢復過來。

(1)最簡單,最常用的方法就是進行系統的重新啟動,不過這種方法代價很大,它意味著在這之前所有的程序已經完成的計算工作都將付之東流,包括參與死鎖的那些程序,以及未參與死鎖的程序。

(2)殺死程序,剝奪資源。終止參與死鎖的程序,收回它們占有的資源,從而解除死鎖。這時又分兩種情況:一次性撤消參與死鎖的全部程序,剝奪全部資源;或者逐步撤消參與死鎖的程序,逐步收回死鎖程序占有的資源。一般來說,選擇逐步撤消的程序時要按照一定的原則進行,目的是撤消那些代價最小的程序,比如按程序的優先順序確定程序的代價;考慮程序執行時的代價和與此程序相關的外部作業的代價等因素。

Linux下的死鎖

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

linux多執行緒下之死鎖

出現死鎖需要同時滿足四個條件,有乙個不具備,系統就不會出現死鎖。互斥條件。即某個資源在一段時間內只能由乙個程序占有,不能同時被兩個或兩個以上的程序占有。這種獨佔資源如cd rom驅動器,印表機等等,必須在占有該資源的程序主動釋放它之後,其它程序才能占有該資源。這是由資源本身的屬性所決定的。如獨木橋就...

Linux 死鎖例子

死鎖是在編寫多執行緒併發時候所需要考慮的問題,在多執行緒軟體使用多個互斥鎖來保護共享資源時,如果設計不合理會出現多個鎖相互巢狀並且都在等待彼此的鎖被釋放,這樣就會出現死鎖現象,讓系統掛起一直相互等待下去。下面給個例子說明這一現象 標頭檔案 include include include includ...