死結的產生原因和解除

來源:互聯網
上載者:User

死結的定義

如果一組進程中的每一個進程都在等待僅由該組進程中的其他進程才能引發的時間,那麼該組進程是死結的。

產生死結的必要條件 互斥條件:簡單的說就是進程搶奪的資源必須是臨界資源,一段時間內,該資源只能同時被一個進程所佔有 請求和保持條件:當一個進程持有了一個(或者更多)資源,申請另外的資源的時候發現申請的資源被其他進程所持有,當前進程阻塞,但不會是放自己所持有的資源 不可搶佔條件:進程已經獲得的資源在未使用完畢的情況下不可被其他進程所搶佔 迴圈等待條件:發生死結的時候,必然存在一個進程—資源的迴圈鏈

這裡所說的資源不僅包括硬體資源或者其他的資源,還包括鎖,鎖也是一種資源,鎖的爭用也會導致死結 死結的幾個例子(為了好描述,這裡用鎖作為資源來描述死結,這裡的鎖換成資源完全沒問題)

自死結,簡單的說一個進程持有了一個鎖之後,在臨界區內又去申請該鎖,它將不得不等待該鎖被釋放,但因為它本身在等待申請該鎖,所以永遠不會有機會釋放鎖並得到鎖,最終結果就是死結。因為很多鎖都不是可遞迴鎖,所以不要嘗試在一個線程內多次申請同一個鎖。

ABBA死結(該死結常發生於多個進程多個鎖),簡單的說就是每個進程都持有其他進程想要獲得的鎖,上圖

 

 

這個最經典的例子當屬,哲學家用餐問題(不再多說,基本原理就是上圖和上面所說的ABBA死結,可以百度一下)

死結的處理方法又分為好幾大類 預防死結

預防死結的辦法就是破壞死結的四個必要條件,只要破壞了條件,死結自然就不會產生了,簡單的描述一下破壞四個條件的思想

破壞請求和保持條件:

1.所有進程在開始運行之前,必須一次性獲得所有資源,如果無法獲得完全,釋放已經獲得的資源,等待;

2.所有進程在開始運行之前,只獲得初始運行所需要的資源,然後在運行過程中不斷請求新的資源,同時釋放自己已經用完的資源。    

相比第一種而言,第二種方式要更加節省資源,不會浪費(因為第一種可能出現一種資源只在進程結束用那麼一小下,但卻從頭到尾都被佔用,使用效率極低),而且,減少了進程饑餓的情況。

破壞不可搶佔條件:

說起來簡單,只要當一個進程申請一個資源,然而卻申請不到的時候,必須釋放已經申請到的所有資源。但是做起來很複雜,需要付出很大的代價,加入該進程已經持有了類似印表機(或者其他的有必要連續工作的)這樣的裝置,申請其他資源的時候失敗了,必須釋放印表機資源,但是人家用印表機已經用過一段時間了,此時釋放印表機資源很可能造成之後再次是用印表機時兩次啟動並執行資訊不連續(得不到正確的結果)

破壞迴圈等待條件:

設立一個規則,讓進程擷取資源的時候按照一定的順序依次申請,不能違背這個順序的規則。必須按照順序申請和釋放,想要申請後面的資源必須先把該資源之前的資源全部申請,想要申請前面的資源必須先把該資源之後的資源(前提是已獲得)全部釋放

破壞互斥條件:

沒法破壞,是資源本身的性質所引起的 避免死結

最常聽到的演算法來襲。銀行家演算法來了。。

銀行家演算法需要的資料結構:1.可利用資源向量(Available);2.最大需求矩陣(Max);3.分配矩陣(Allocation);4.需求矩陣(Need)。

上述三個矩陣存在如下關係  Need[i,j]=Max[i,j]-Allocation[i,j];

說的看似很難懂的樣子,下面詳解一下就很好理解了。


可利用資源向量(Available):這麼說吧,比如當前有三種資源A,B,C,可利用資源向量就是一個數組(為了在程式中使用),我們理解的話就說ABC各有多少個資源,例子

A  B  C

7  2  5     

這裡7,2,5三個資源的數目組合起來就是一個數組(向量)

 

最大需求矩陣(Max):說是矩陣完全是為了在編程時使用方便(就是一個二維數組),我們理解的話就說是進程工作需要的每個資源的總數目,例子

     A   B   C

P1    1   1   1   

這樣一看就明白了,進程P1需要三種資源各一個(這個不是二維數組啊,是一維的。怎麼可能只有一個進程這是一對進程思死結的解決辦法。),多加幾個進程就二維數組了

分配矩陣(Allocation):和需求矩陣類似,只是數值的含義變成了,目前已經給進程某某(行值i),分配了多少的某某(列值j)資源

需求矩陣(Need):根據上面的公式就可以看出,這個是進程目前還需要多少資源才可以運行,和最大需求不一樣,最大需求是一共需要的數目。

有了這些我們使用銀行家演算法就夠了,我們使用該演算法的目的是什麼。是避免死結,避免死結的意思就是我們使用這些資料結構來推斷如果按某種順序執行進程隊列,是否是安全的(是否會造成死結)

 

上圖是一個簡單的圖執行個體,為了電腦程式運行方便,我們一般假設從P0進程開始運行,那麼就要給P0分配足夠啟動並執行資源(就是把NEED都給了,前提是當前Available資源數目足夠該進程的Need),然後計算Available(new)=Available(old)+Allocation(P),其中Allocation就是執行的進程之前已經分配的資源執行完成之後自然要會收到Available裡。

題目一般都會給上圖的表,然後讓你寫出安全序列,用當前的Available看滿足哪個進程的Need然後就先執行它,執行完後回收(加到Available中)該進程的Allocation就可以了,這樣一步一步算到最後如果Available一直算下來沒有虧損不夠的情況證明這個序列就是一個安全隊列了~。

  死結的檢測和解除

使用類似銀行家演算法的方式就可以簡單的檢測死結

死結解除:

1.終止進程(簡單粗暴),就是字面上的,你們死結了,我就把你們一起殺掉,缺點就是如果一個進程跑了很長時間,但是被殺了,還得從頭來。

2.逐個終止進程,按照某種順序,挨個殺死進程,每殺一個進程就去看看死結解除了沒有(每殺一個進程都會釋放一些資源,如果釋放好粗來的資源解決了死結問題,就沒必要再濫殺無辜了),沒解除就繼續殺。

第二種方式顯然人性化了許多,但是按照某種順序顯得很朦朧,這裡的某種順序就是指死結解除演算法,有很多,這裡不再贅述。


注意:

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.