1. 程式人生 > >死鎖的定義 產生原因 必要條件 避免死鎖和解除死鎖的方法

死鎖的定義 產生原因 必要條件 避免死鎖和解除死鎖的方法

               

1.死鎖:如果一組程序中的每一個程序都在等待僅由該組程序中的其它程序才能引發的事件,那麼該組程序是死鎖的。

2.產生死鎖的原因:

(1)競爭不可搶佔性資源。

(2)競爭可消耗資源。

    當系統中供多個程序共享的資源如印表機,公用佇列等,其數目不足以滿足諸程序的需要時,會引起諸程序對資源的競爭而產生死鎖。

(3)程序推進順序不當

        程序在執行過程中,請求和釋放資源的順序不當,也同樣會導致產生程序死鎖。

如果系統資源充足,程序的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則就會因爭奪有限的資源而陷入死鎖。其次,程序執行推進順序與速度不同,也可能產生死鎖。

      一個執行緒也可引起死鎖。

3.產生死鎖的四個必要條件:

(1) 互斥條件:一個資源每次只能被一個程序使用。

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

(3) 不可搶佔條件:程序已獲得的資源,在末使用完之前,不能強行剝奪

只能在程序使用完時由自己釋放。

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

這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。因此可以寫下如下的預防死鎖的方法

4.避免死鎖的方法:

1破壞“互斥”條件:就是在系統裡取消互斥。若資源不被一個程序獨佔使用,那麼死鎖是肯定不會發生的。但一般“互斥”條件是無法破壞的。因此,在死鎖預防裡主要是破壞其他個必要條件,而不去涉及破壞“互斥”條件。

2破壞“請求和保持”條件:在系統中不允許程序在已獲得某種資源的情況下,申請其他資源。即要想出一個辦法,阻止程序在持有資源的同時申請其他資源。

方法一:所有程序在執行之前,必須一次性地申請在整個執行過程中所需的全部資源。這樣,該程序在整個執行期間,便不會再提出資源請求,從而破壞了“請求”條件。系統在分配資源時,只要有一種資源不能滿足程序的要求,即使其它所需的各資源都空閒也不分配給該程序,而讓該程序等待。由於該程序在等待期間未佔有任何資源,於是破壞了“保持”條件。

該方法優點:簡單、易行且安全。

缺點:a.資源被嚴重浪費,嚴重惡化了資源的利用率。

      b.使程序經常會發生飢餓現象。

方法二:要求每個程序提出新的資源申請前,釋放它所佔有的資源。這樣,一個程序在需要資源S時,須先把它先前佔有的資源R釋放掉,然後才能提出對S的申請,即使它可能很快又要用到資源R。

3破壞“不可搶佔”條件:允許對資源實行搶奪。
方法一:如果佔有某些資源的一個程序進行進一步資源請求被拒絕,則該程序必須釋放它最初佔有的資源,如果有必要,可再次請求這些資源和另外的資源。
方法二:如果一個程序請求當前被另一個程序佔有的一個資源,則作業系統可以搶佔另一個程序,要求它釋放資源。只有在任意兩個程序的優先順序都不相同的條件下,方法才能預防死鎖。

4破壞“迴圈等待”條件:將系統中的所有資源統一編號,程序可在任何時刻提出資源申請,但所有申請必須按照資源的編號順序(升序)提出。這樣做就能保證系統不出現死鎖。

利用銀行家演算法避免死鎖:

銀行家演算法:

設程序i提出請求Request[j],則銀行家演算法按如下規則進行判斷。

(1) 如果Request[j]≤Need[i,j],則轉向(2),否則認為出錯因為它所需要的資源數已超過它所宣佈的最大值

(2) 如果Request[j]≤Available[j],則轉向(3);否則表示尚無足夠資源,Pi需等待。

(3) 假設程序i的申請已獲批准,於是修改系統狀態:

Available[j]=Available[j]-Request[i]

Allocation[i,j]=Allocation[i,j]+Request[j]

Need[i,j]=Need[i,j]-Request[j]

(4)系統執行安全性檢查,如安全,則分配成立;否則試探險性分配作廢,系統恢復原狀,程序等待。

安全性演算法

(1) 設定兩個工作向量Work=Available;Finish[i]=False

(2) 從程序集合中找到一個滿足下述條件的程序,

     Finish [i]=False;

     Need[i,j]≤Work[j];

     如找到,執行(3);否則,執行(4)

(3) 設程序獲得資源,可順利執行,直至完成,從而釋放資源。

    Work[j]=Work[j]+Allocation[i,j];

    Finish[i]=True;

    go to step 2;

(4) 如所有的程序Finish[i]=true,則表示安全;否則系統不安全。

5.死鎖的解除:

一旦檢測出死鎖,就應立即釆取相應的措施,以解除死鎖。死鎖解除的主要兩種方法:

1) 搶佔資源。從一個或多個程序中搶佔足夠數量的資源,分配給死鎖程序,以解除死鎖狀態。

2) 終止(或撤銷程序。終止(或撤銷)系統中的一個或多個死鎖程序直至打破迴圈環路,使系統從死鎖狀態解脫出來。

總結:

       一般情況下,如果同一個執行緒先後兩次呼叫lock,在第二次呼叫時,由於鎖已經被佔用,該執行緒會掛起等待別的執行緒釋放鎖,然而鎖正是被自己佔用著的,該執行緒又被掛起而沒有機會釋放鎖,因此就永遠處於掛起等待狀態了,這叫做死鎖(Deadlock)。另⼀一種典型的死鎖情形是這樣:執行緒A獲得了鎖1,執行緒B獲得了鎖2,這時執行緒A調⽤用lock試圖獲得鎖2,結果是需要掛起等待執行緒B釋放鎖2,而這時執行緒B也調⽤用lock試圖獲得鎖1,結果是需要掛起等待執行緒A釋放鎖1,於是執行緒A和B都永遠處於掛起狀態了。

注意:

      寫程式時應該儘量避免同時獲得多個鎖,如果一定有必要這麼做,則有一個原則:如果所有執行緒在需要多個鎖時都按相同的先後順序(常見的是按Mutex變數的地址順序)獲得鎖,則不會出現死鎖。比如一個程式中用到鎖1、鎖2、鎖3,它們所對應的Mutex變數的地址是鎖1<鎖2<鎖3,那麼所有執行緒在需要同時獲得2個或3個鎖時都應該按鎖1、鎖2、鎖3的順序獲得。如果要為所有的鎖確定一個先後順序比較困難,則應pthread_mutex_trylock呼叫代替pthread_mutex_lock 呼叫,以免死鎖。


 

 

死鎖產生的原因和必要條件及預防死鎖的方法及死鎖的檢測與解除

 

           

再分享一下我老師大神的人工智慧教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智慧的隊伍中來!https://blog.csdn.net/jiangjunshow