1. 程式人生 > >死鎖的原因,和一般的解決方案

死鎖的原因,和一般的解決方案

死鎖的條件

一般來說,要出現死鎖問題需要滿足以下條件:

1. 互斥條件:一個資源每次只能被一個執行緒使用。

2. 請求與保持條件:一個程序因請求資源而阻塞時,對已獲得的資源保持不放。

3. 不剝奪條件:程序已獲得的資源,在未使用完之前,不能強行剝奪。

4. 迴圈等待條件:若干程序之間形成一種頭尾相接的迴圈等待資源關係。

只要破壞死鎖 4 個必要條件之一中的任何一個,死鎖問題就能被解決。

死鎖解決方案

死鎖是由四個必要條件導致的,所以一般來說,只要破壞這四個必要條件中的一個條件,死鎖情況就應該不會發生。

  1. 如果想要打破互斥條件,我們需要允許程序同時訪問某些資源,這種方法受制於實際場景,不太容易實現條件;
  2. 打破不可搶佔條件,這樣需要允許程序強行從佔有者那裡奪取某些資源,或者簡單一點理解,佔有資源的程序不能再申請佔有其他資源,必須釋放手上的資源之後才能發起申請,這個其實也很難找到適用場景;
  3. 程序在執行前申請得到所有的資源,否則該程序不能進入準備執行狀態。這個方法看似有點用處,但是它的缺點是可能導致資源利用率和程序併發性降低;
  4. 避免出現資源申請環路,即對資源事先分類編號,按號分配。這種方式可以有效提高資源的利用率和系統吞吐量,但是增加了系統開銷,增大了程序對資源的佔用時間。

如果我們在死鎖檢查時發現了死鎖情況,那麼就要努力消除死鎖,使系統從死鎖狀態中恢復過來。消除死鎖的幾種方式:

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

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

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