tft每日頭條

 > 生活

 > 死鎖的避免策略

死鎖的避免策略

生活 更新时间:2024-11-25 19:27:37
本文目的

本文旨在向大家詳細地介紹死鎖,包括死鎖産生的原因,産生的條件,解決方法,以及如何預防。

死鎖是什麼

所謂死鎖:是指兩個或兩個以上的進程在執行過程中,因争奪資源而造成的一種互相等待的現象,若無外力作用,它們都将無法推進下去。此時稱系統處于死鎖狀态或系統産生了死鎖,這些永遠在互相等待的進程稱為死鎖進程。由于資源占用是互斥的,當某個進程提出申請資源後,使得有關進程在無外力協助下,永遠分配不到必需的資源而無法繼續運行,這就産生了一種特殊現象死鎖。

死鎖的避免策略(學習筆記-死鎖的詳細介紹)1

示例

當線程A持有獨占鎖a,并嘗試去獲取獨占鎖b的同時,線程B持有獨占鎖b,并嘗試獲取獨占鎖a的情況下,就會發生AB兩個線程由于互相持有對方需要的鎖,而發生的阻塞現象,我們稱為死鎖。

public class DeadLockDemo { public static void main(String[] args) { // 線程a Thread td1 = new Thread(new Runnable() { public void run() { DeadLockDemo.method1(); } }); // 線程b Thread td2 = new Thread(new Runnable() { public void run() { DeadLockDemo.method2(); } }); td1.start(); td2.start(); } public static void method1() { synchronized (String.class) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程a嘗試獲取integer.class"); synchronized (Integer.class) { } } } public static void method2() { synchronized (Integer.class) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程b嘗試獲取String.class"); synchronized (String.class) { } } } } ---------------- 線程b嘗試獲取String.class 線程a嘗試獲取integer.class.......... 無限阻塞下去

産生條件

雖然進程在運行過程中,可能發生死鎖,但死鎖的發生也必須具備一定的條件,死鎖的發生必須具備以下四個必要條件。

1)互斥條件:指進程對所分配到的資源進行排它性使用,即在一段時間内某資源隻由一個進程占用。如果此時還有其它進程請求資源,則請求者隻能等待,直至占有資源的進程用畢釋放。

2)請求和保持條件:指進程已經保持至少一個資源,但又提出了新的資源請求,而該資源已被其它進程占有,此時請求進程阻塞,但又對自己已獲得的其它資源保持不放。

3)不剝奪條件:指進程已獲得的資源,在未使用完之前,不能被剝奪,隻能在使用完時由自己釋放。

4)環路等待條件:指在發生死鎖時,必然存在一個進程——資源的環形鍊,即進程集合{P0,P1,P2,···,Pn}中的P0正在等待一個P1占用的資源;P1正在等待P2占用的資源,……,Pn正在等待已被P0占用的資源。

死鎖的避免策略(學習筆記-死鎖的詳細介紹)2

産生原因

死鎖産生原因主要有兩種,一種是競争資源引起的,另一種是進程推進順序異常引起的。

1,競争資源

産生死鎖中的競争資源指的是競争不可剝奪資源和臨時資源。

死鎖的避免策略(學習筆記-死鎖的詳細介紹)3

可剝奪資源和不可剝奪資源

可剝奪資源,是指某進程在獲得這類資源後,該資源可以再被其他進程或系統剝奪。例如,優先權高的進程可以剝奪優先權低的進程的處理機。又如,内存區可由存儲器管理程序,把一個進程從一個存儲區移到另一個存儲區,此即剝奪了該進程原來占有的存儲區,甚至可将一進程從内存調到外存上,可見,CPU和主存均屬于可剝奪性資源。

不可剝奪資源,是指當系統把這類資源分配給某進程後,再不能強行收回,隻能在進程用完後自行釋放,如磁帶機、打印機等。

競争不可剝奪資源

在系統中所配置的不可剝奪資源,由于它們的數量不能滿足諸進程運行的需要,會使進程在運行過程中,因争奪這些資源而陷于僵局。例如,系統中隻有一台打印機R1和一台磁帶機R2,可供進程P1和P2共享。假定PI已占用了打印機R1,P2已占用了磁帶機R2,若P2繼續要求打印機R1,P2将阻塞;P1若又要求磁帶機,P1也将阻塞。于是,在P1和P2之間就形成了僵局,兩個進程都在等待對方釋放自己所需要的資源,但是它們又都因不能繼續獲得自己所需要的資源而不能繼續推進,從而也不能釋放自己所占有的資源,以緻進入死鎖狀态。

競争臨時資源

上面所說的打印機資源屬于可順序重複使用型資源,稱為永久資源。還有一種所謂的臨時資源,這是指由一個進程産生,被另一個進程使用,短時間後便無用的資源,故也稱為消耗性資源,如硬件中斷、信号、消息、緩沖區内的消息等,它也可能引起死鎖。例如,SI,S2,S3是臨時性資源,進程P1産生消息S1,又要求從P3接收消息S3;進程P3産生消息S3,又要求從進程P2處接收消息S2;進程P2産生消息S2,又要求從P1處接收産生的消息S1。如果消息通信按如下順序進行:

P1: ···Relese(S1);Request(S3); ···

P2: ···Relese(S2);Request(S1); ···

P3: ···Relese(S3);Request(S2); ···

并不可能發生死鎖。但若改成下述的運行順序:

P1: ···Request(S3);Relese(S1);···

P2: ···Request(S1);Relese(S2); ···

P3: ···Request(S2);Relese(S3); ···

則可能發生死鎖。

2,進程推進順序不當引起死鎖

由于進程在運行中具有異步性特征,這可能使P1和P2兩個進程按下述兩種順序向前推進。

1) 進程推進順序合法

當進程P1和P2并發執行時,如果按照下述順序推進:

P1:Request(R1);

P1:Request(R2);

P1: Relese(R1);

P1: Relese(R2);

P2:Request(R2);

P2:Request(R1);

P2: Relese(R2);

P2: Relese(R1);

這兩個進程便可順利完成,這種不會引起進程死鎖的推進順序是合法的。

2) 進程推進順序非法

若P1保持了資源R1,P2保持了資源R2,系統處于不安全狀态,因為這兩個進程再向前推進,便可能發生死鎖。例如,當P1運行到P1:Request(R2)時,将因R2已被P2占用而阻塞;當P2運行到P2:Request(R1)時,也将因R1已被P1占用而阻塞,于是發生進程死鎖。

處理方式

在系統中已經出現死鎖後,應該及時檢測到死鎖的發生,并采取适當的措施來解除死鎖。目前處理死鎖的方法可歸結為以下四種:

1) 預防死鎖。

這是一種較簡單和直觀的事先預防的方法。方法是通過設置某些限制條件,去破壞産生死鎖的四個必要條件中的一個或者幾個,來預防發生死鎖。預防死鎖是一種較易實現的方法,已被廣泛使用。但是由于所施加的限制條件往往太嚴格,可能會導緻系統資源利用率和系統吞吐量降低。

由于資源互斥是資源使用的固有特性是無法改變的。所以隻能通過破壞其餘三個條件來預防死鎖。

破壞“不可剝奪”條件:一個進程不能獲得所需要的全部資源時便處于等待狀态,等待期間他占有的資源将被隐式的釋放重新加入到 系統的資源列表中,可以被其他的進程使用,而等待的進程隻有重新獲得自己原有的資源以及新申請的資源才可以重新啟動,執行。

破壞”請求與保持“條件:第一種方法靜态分配即每個進程在開始執行時就申請他所需要的全部資源。第二種是動态分配即每個進程在申請所需要的資源時他本身不占用系統資源。

破壞“循環等待”條件:采用資源有序分配其基本思想是将系統中的所有資源順序編号,将緊缺的,稀少的采用較大的編号,在申請資源時必須按照編号的順序進行,一個進程隻有獲得較小編号的進程才能申請較大編号的進程。

2) 避免死鎖。

該方法同樣是屬于事先預防的策略,但它并不須事先采取各種限制措施去破壞産生死鎖的的四個必要條件,而是在資源的動态分配過程中,用某種方法去防止系統進入不安全狀态,從而避免發生死鎖。

預防死鎖的幾種策略,會嚴重地損害系統性能。因此在避免死鎖時,要施加較弱的限制,從而獲得 較滿意的系統性能。由于在避免死鎖的策略中,允許進程動态地申請資源。因而,系統在進行資源分配之前預先計算資源分配的安全性。若此次分配不會導緻系統進入不安全的狀态,則将資源分配給進程;否則,進程等待。其中最具有代表性的避免死鎖算法是銀行家算法。

銀行家算法:(詳見學習筆記-銀行家算法首先需要定義狀态和安全狀态的概念。系統的狀态是當前給進程分配的資源情況。因此,狀态包含兩個向量Resource(系統中每種資源的總量)和Available(未分配給進程的每種資源的總量)及兩個矩陣Claim(表示進程對資源的需求)和Allocation(表示當前分配給進程的資源)。安全狀态是指至少有一個資源分配序列不會導緻死鎖。當進程請求一組資源時,假設同意該請求,從而改變了系統的狀态,然後确定其結果是否還處于安全狀态。如果是,同意這個請求;如果不是,阻塞該進程知道同意該請求後系統狀态仍然是安全的。

3)檢測死鎖。

這種方法并不須事先采取任何限制性措施,也不必檢查系統是否已經進入不安全區,此方法允許系統在運行過程中發生死鎖。但可通過系統所設置的檢測機構,及時地檢測出死鎖的發生,并精确地确定與死鎖有關的進程和資源,然後采取适當措施,從系統中将已發生的死鎖清除掉。

首先為每個進程和每個資源指定一個唯一的号碼;

然後建立資源分配表和進程等待表。

4)解除死鎖。

  這是與檢測死鎖相配套的一種措施。當檢測到系統中已發生死鎖時,須将進程從死鎖狀态中解脫出來。常用的實施方法是撤銷或挂起一些進程,以便回收一些資源,再将這些資源分配給已處于阻塞狀态的進程,使之轉為就緒狀态,以繼續運行。死鎖的檢測和解除措施,有可能使系統獲得較好的資源利用率和吞吐量,但在實現上難度也最大。

剝奪資源:從其它進程剝奪足夠數量的資源給死鎖進程,以解除死鎖狀态;

撤消進程:可以直接撤消死鎖進程或撤消代價最小的進程,直至有足夠的資源可用,死鎖狀态.消除為止;所謂代價是指優先級、運行代價、進程的重要性和價值等。

本文的初衷為學習筆記的分享,部分圖文來源于網絡,如侵,聯删。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved