產生死鎖的原因和必要條件:
產生死鎖的原因:
1.競爭資源。當系統中供多個進程共享的資源如打印機,公用隊列等,其數目不足以滿足諸進程的需要時,會引起諸進程對資源的競爭而產生死鎖。
2.進程推進順序非法。進程在運行過程中,請求和釋放資源的順序不當,也同樣會導致產生進程死鎖。
如果系統資源充足,進程的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則就會因爭奪有限的資源而陷入死鎖。其次,進程運行推進順序與速度不同,也可能產生死鎖。
產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關係。
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖。
預防死鎖的方法:
1.破壞“互斥”條件:就是在系統裏取消互斥。若資源不被一個進程獨佔使用,那麼死鎖是肯定不會發生的。但一般來說在所列的四個條件中,“互斥”條件是無法破壞的。因此,在死鎖預防裏主要是破壞其他幾個必要條件,而不去涉及破壞“互斥”條件。
2.破壞“佔有並等待”條件:破壞“佔有並等待”條件,就是在系統中不允許進程在已獲得某種資源的情況下,申請其他資源。即要想出一個辦法,阻止進程在持有資源的同時申請其他資源。
方法一:創建進程時,要求它申請所需的全部資源,系統或滿足其所有要求,或什麼也不給它。這是所謂的 “ 一次性分配”方案。
方法二:要求每個進程提出新的資源申請前,釋放它所佔有的資源。這樣,一個進程在需要資源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[i]+Allocation[i,j];
Finish[i]=True;
go to step 2;
(4) 如所有的進程Finish[i]=true,則表示安全;否則系統不安全。
代碼實現:https://github.com/wangiijing/banker-s-algorithm
死鎖的檢測與解除:
資源分配圖:
系統死鎖,可利用資源分配圖來描述。如圖2-17所示,用圓圈代表一個進程,用框代表一類資源。由於一種類型的資源可能有多個,用框中的一個點代表一類資源中的一個資源。從進程到資源的有向邊叫請求邊,表示該進程申請一個單位的該類資源;從資源到進程的邊叫分配邊,表示該類資源已經有一個資源被分配給了該進程。
在圖2-17所示的資源分配圖中,進程P1已經分得了兩個R1資源,並又請求一個R2 資源;進程P2分得了一個R1和一個R2資源,並又請求一個R1資源。
死鎖定理:
可以通過將資源分配圖簡化的方法來檢測系統狀態S是否爲死鎖狀態。簡化方法如下:
1) 在資源分配圖中,找出既不阻塞又不是孤點的進程Pi(即找出一條有向邊與它相連,且該有向邊對應資源的申請數量小於等於系統中已有空閒資源數量。若所有的連接該進程的邊均滿足上述條件,則這個進程能繼續運行直至完成,然後釋放它所佔有的所有資源)。消去它所有的請求邊和分配邊,使之成爲孤立的結點。在圖2-18(a)中,P1是滿足這一條件的進程結點,將P1的所有邊消去,便得到圖248(b)所示的情況。
2) 進程Pi所釋放的資源,可以喚醒某些因等待這些資源而阻塞的進程,原來的阻塞進程可能變爲非阻塞進程。在圖2-17中,進程P2就滿足這樣的條件。根據第1) 條中的方法進行一系列簡化後,若能消去圖中所有的邊,則稱該圖是可完全簡化的,如圖2-18(c)所示。
S爲死鎖的條件是當且僅當S狀態的資源分配圖是不可完全簡化的,該條件爲死鎖定理。
死鎖的解除:
一旦檢測出死鎖,就應立即釆取相應的措施,以解除死鎖。死鎖解除的主要方法有:
1) 資源剝奪法。掛起某些死鎖進程,並搶佔它的資源,將這些資源分配給其他的死鎖進程。但應防止被掛起的進程長時間得不到資源,而處於資源匱乏的狀態。
2) 撤銷進程法。強制撤銷部分、甚至全部死鎖進程並剝奪這些進程的資源。撤銷的原則可以按進程優先級和撤銷進程代價的高低進行。
3) 進程回退法。讓一(多)個進程回退到足以迴避死鎖的地步,進程回退時自願釋放資源而不是被剝奪。要求系統保持進程的歷史信息,設置還原點。