死鎖及處理


所謂死鎖就是一個進程集合中的多個進程因為競爭資源,而造成的互相等待現象。很顯然,如果沒有外力的作用,那么死鎖涉及到的各個進程都將永遠處於封鎖狀態。

產生死鎖的原因主要是:
(1) 因為系統資源不足。
(2) 進程運行推進的順序不合適。
(3) 資源分配不當等。

死鎖的必要條件:

    互斥條件Mutual exclusion):資源不能被共享,只能由一個進程使用。

    請求與保持條件Hold and wait):已經得到資源的進程可以再次申請新的資源。

    非剝奪條件No pre-emption):已經分配的資源不能從相應的進程中被強制地剝奪。

    循環等待條件Circular wait):系統中若干進程組成環路,改環路中每個進程都在等待相鄰進程正占用的資源。

這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。

  前面介紹了死鎖發生時的四個必要條件,只要破壞這四個必要條件中的任意一個條件,死鎖就不會發生。這就為我們解決死鎖問題提供了可能。一般地,解決死鎖的方法分為死鎖的預防,避免,檢測與恢復三種,當然還一種是忽略該問題,例如鴕鳥算法,該算法可以應用在極少發生死鎖的情況下。

 

死鎖的預防  

 

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

 

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

 

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

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

 

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

 

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

 

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

 

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

 

(1)限制了進程對資源的請求,同時給系統中所有資源合理編號也是件困難事,並增加了系統開銷;

 

(2)為了遵循按編號申請的次序,暫不使用的資源也需要提前申請,從而增加了進程對資源的占用時間。

 

死鎖的避免  

 

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

 

1.安全序列

 

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

 

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

 

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

 

2.銀行家算法

 

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

 

  [背景知識] 

 

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

 

  [問題的描述]

 

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

 

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

 

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

 

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

 

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

 

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

 

 死鎖的檢測與恢復  

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

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

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

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

  此外,還有進程回退策略,即讓參與死鎖的進程回退到沒有發生死鎖前某一點處,並由此點處繼續執行,以求再次執行時不再發生死鎖。雖然這是個較理想的辦法,但是操作起來系統開銷極大,要有堆棧這樣的機構記錄進程的每一步變化,以便今后的回退,有時這是無法做到的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM