OS不做人系列四之華爾街銀行家

目錄

前言:

 一、資源問題

二、死鎖發生必要條件

三、預防死鎖

四、死鎖避免

五、死鎖的檢測與解除(可以當做概念簡單瞭解一下,重點是銀行家算法哦)

後記:


前言:

      大家好啊,歡迎來到了不做人系列的第四期,前面我們介紹同步互斥,各種進程騷操作,各種搶佔資源,所以我們發現會出現死鎖,大家都阻塞了,這樣會浪費大量的系統資源,甚至導致系統的崩潰。所以我們需要擁有銀行家的敏銳來處理死鎖。那麼我們一起來學習吧。

          先給出死鎖概念吧,後面你會更加深刻的理解它:指兩個或多個併發進程各自佔有某種資源而又等待別的進程釋放它們的資源的狀態。

 

 一、資源問題

     在系統中有許多不同種類的資源,其中可以引起死鎖的主要是,需要採用互斥訪問方法的、不可以被搶佔的資源,即臨界資源。哈哈,突然想到了錢是萬惡之源。我們接下來就來介紹一下資源分類吧:

1.可重用性資源和消耗性資源

1)可重用性資源

     可重用性資源是一種可供用戶重複使用多次的資源,有如下性質:

(1)每一個可重用性資源只可以分給一個進程使用,不允許多個進程共享。

(2)進程在使用可重用性功能時,必須按照這樣的順序:

  • 請求資源,如果請求資源失敗,請求進程將會被阻塞或循環等待
  • 使用資源
  • 釋放資源

(3)系統中每一類可重用性資源中的單元數目是相對固定的,進程在運行期間既不能創建也不能刪除它。

2)可消耗性資源

     可消耗性資源又被稱爲臨時性資源,它是進程運行期間,由進程動態的創建和消耗的,有如下性質:

  • 每一類可消耗性資源的單元數目在進程運行期間是可以不斷變化的
  • 進程在運行過程中,可以不斷的創造可消耗性資源
  • 進程在運行過程中,可以請求若干個資源的消耗

 

2.可搶佔性資源和不可搶佔性資源

1)可搶佔性資源

     例如:優先級高的進程可以搶佔優先級低的進程的處理機。

2)不可搶佔資源

     例如:進程讀取一個不可分割完整數據的時候,不可以中斷。

 

-------->  所以競爭不可搶佔性資源會引起死鎖

--------> 競爭可消耗性資源會引起死鎖

--------> 進程推進順序不當引起死鎖

 


二、死鎖發生必要條件

我們將進程分組的話,這裏再給出死鎖定義:

     如果一組進程中的每一個進程都在等待僅由該組進程中的其它進程才能引發的事件,那麼該組進程時死鎖的(Deadlock)。

      所以我們可以歸納一下死鎖發生的必要條件(必要條件在這裏的意思是:如果沒有這四個條件,那麼一定不會發生死鎖(這裏只要任意一個不成立,死鎖就不會發生,如果發生有這四個條件,未必會發生死鎖,這是離散數學的知識哦,高中也有)。

(1)互斥條件

(2)請求和保持條件

(3)不可搶佔條件

(4)循環等待條件

 

這裏舉一個食堂吃飯的例子:

      加入食堂筷子在東邊,碗筷在西邊。張三和王四來了,只有一雙筷子和一個碗,張三往東邊跑,王四往西邊跑,兩人各自拿了一雙筷子和一個碗。沒辦法,死鎖了。

      如果他們是朋友可以接受公用,那麼互斥條件就不成立了,死鎖不會發生。

     如果張三或者王四願意先給對方,那麼保持條件就不成立了,死鎖不會發生。

     如果張三搶了王四的,不可搶佔條件不成立了,死鎖不會發生。

     如果張三王四一看只有一雙碗筷了,不等待出去吃了,那麼循環等待條件不成立了,死鎖不會發生。

 


三、預防死鎖

1.破壞請求和保持條件

 1)第一種協議

     所以進程在開始運行之前必須一次性的申請其在整個運行過程中所需要的全部資源。這不就破壞了請求條件嗎?但是缺點就是資源浪費嚴重,會發生飢餓現象。

2)第二種協議

     允許一個進程只獲得運行初期所需的資源後,便開始運行。進程運行過程中再逐步釋放已分配給自己的、且已用畢的全部資源,然後再請求新的資源。

2.破壞不可搶佔條件

     可以規定當一個已擁有一定不可搶佔資源的進程,請求新資源而得不到時,就釋放自己的資源。

3.破壞循環等待條件

    我們可以對所有的資源進行線性排序,並賦予不同的序列號。就像上面舉的食堂的例子,只要都編號就好了。

 


四、死鎖避免

     上面的預防很有用,但是很多時候出於無奈我們都要滿足這四個條件,所以我們要有銀行家的思維,去看到後面的很多步,如果會死鎖,那我就不走了。就像下象棋,高手總是能看到後面的第n步,反正我就頂破天那麼2,3步,hahhaha

     好的,那麼就來到了我們標題中提到的銀行家算法:

     這個是迪傑斯特拉大牛提出來的,當時是爲了銀行工作的算法,就是避免發生交易失敗導致損失。

     爲實現銀行家算法,每一個新進程在進入系統時,它必須申明在運行過程中,可能需要美中資源類型的最大單位數目,其數目不應超過系統擁有的資源總量。當進程請求一組資源時,系統必須首先確定是否有足夠的資源分配給該進程。若有,再進一步計算在將這些資源分配給進程後,是否會使系統處於不安全狀態。如果不會,纔將資源分配給它,否則讓進程等待。

那好,這裏提及一下安全狀態:

     安全狀態:

如果存在一個由系統中所有進程構成的安全序列p1,p2...pn,則系統處於安全狀態。

     安全序列:

存在一個進程序列,如果對於每個進程Pi(1<=i<=n),它以後尚需要的資源量不超過系統當前剩餘資源量與所有進程當前佔有資源量之和,那麼這個序列是安全序列。

     我們從銀行家算法描述那裏可以看到,我們需要四個數據結構:

(1)可利用資源向量Available

(2)最大需求矩陣Max

(3)分配矩陣Allocation

(4)需求矩陣Need

有如下關係:Need[i,j]=Max[i,j]-Allocation[i,j]

 

所以具體銀行家算法如下:

     在說之前可以小題一下,其實思想就是通過資源的判斷來未雨綢繆,哈哈哈

     設Requesti是進程Pi的請求向量,如果Requesti[j] =K,表示進程Pi需要K個Rj類型的資源。當Pi發出資源請求後,系統按下屬步驟進行檢查:

(1)如果Requesti[j]<=Need[i,j],便轉向步驟(2);否則認爲出錯,所需要的資源數已經超過最大值。這個都可以理解,請求的當然不能大於總的需要的呀。

(2)如果Requesti[j]<=Available[j],便轉向步驟(3);否則,表示尚無足夠資源,Pi須等待。在第一步基礎上再次判斷是否足夠。

(3)系統試探着把資源分配給進程Pi,並修改下面數據結構中的數值:

  • Available[j] = Available[j] - Requesti[j];
  • Allocation[i,j] = Allocation[i,j] + Requesti[j];
  • Need[i,j] = Need[i,j] - Requesti[j];

其實就是將資源矩陣改變啦

(4)系統執行安全性算法,檢查此次資源分配後系統是否處於安全狀態。若安全,正式將資源分配給進程Pi,已完成本次分配;否則,將本次的試探分配作廢,恢復原來的狀態,無非就是加減法再次回去。

 

安全性算法如下:

(1)設置兩個向量:

工作向量Work,它表示系統可提供給進程繼續運行所需的各種資源數目,它含有m個元素,在指向安全算法開始時,Work = Available;

Finish:它表示系統是否有足夠的資源分配給進程,使之運行完成。開始時先做Finish[i] = false,有資源則改爲true。

(2)從進程集合中找到一個能滿足下述條件的進程:

首先Finish[i] = false; 然後Need[i,j]<=Work[j];若找到,執行步驟(3);否則,執行步驟(4)

(3)當進程Pi獲得資源後,可順利執行,直至完成,並釋放分配給它的資源,執行:

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

Finish[i] = true;

go to step 2;

(4)如果所有進程的Finish[i] = true都滿足,則表示系統處於安全狀態,否則,處於不安全狀態。

 


五、死鎖的檢測與解除(可以當做概念簡單瞭解一下,重點是銀行家算法哦)

那如果在系統中既不採取死鎖預防措施,也沒有死鎖避免算法,,就很可能發生死鎖。在這種情況下,系統會提供兩個算法:

  • 死鎖檢測算法:用於檢測系統狀態,已確定系統中是否發生了死鎖。
  • 死鎖解除算法:如果發生了死鎖,那麼將系統從死鎖狀態中解脫出來。

這裏大致說一下死鎖解除,比如:搶佔資源來解除,終止進程等方法,關於檢測與解除更多的可以去找度娘理解哦。

 

後記:

     好的,華爾街銀行家告訴我們要學會利用數據來避免某類事情的發生,也許這就是他們這麼有錢的原因吧。銀行家的代碼會在Linux專欄中提到哦,如有誤,請指出,謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章