歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> 學習Linux

死鎖,死鎖的四個必要條件

死鎖,死鎖的四個必要條件


死鎖,死鎖的四個必要條件


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

產生死鎖的必要條件:(產生死鎖必須同時具備下面四個必要條件

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

這裡所說的資源不僅包括硬件資源或者其他的資源,還包括鎖,鎖也是一種資源,鎖的爭用也會導致死鎖

  • 死鎖的幾個例子(為了好描述,這裡用鎖作為資源來描述死鎖,這裡的鎖換成資源完全沒問題)

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

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

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

 

 

推薦書籍:《計算機操作系統(第四版)》第三章第五節,P104

http://xxxxxx/Linuxjc/1141774.html TechArticle

Copyright © Linux教程網 All Rights Reserved