死鎖:死鎖指的是系統(tǒng)中并發(fā)執(zhí)行的多個線程(進程)由于無法獲所需的資源而永久阻塞的狀態(tài)。
死鎖產(chǎn)生的必要條件:
A.排它性互斥:指的是資源在任意時刻只能由一個任務(wù)(線程或進程)使用。如果此時還有其它任務(wù)請求該資源,則請求者只能等待,直至占有資源的任務(wù)釋放資源。
B.不可搶占:指的是當一個任務(wù)擁有某種資源時,除非它主動釋放它,否則無法讓該任務(wù)失去該資源的擁有權(quán)。
C.持有和等待:指的是任務(wù)已經(jīng)擁有了至少一種資源,然后又等待其它資源可用。
D.循環(huán)等待:指在發(fā)生死鎖時,必然存在一個任務(wù)——資源的環(huán)形鏈,即任務(wù)集合{P0,P1,P2,···,Pn}中的P0正在等待一個P1占用的資源;P1正在等待P2占用的資源,……,Pn正在等待已被P0占用的資源。
產(chǎn)生死鎖時這4個必要條件都必須被滿足,因而處理死鎖就是要避免、預(yù)防這4個條件同時成立,或者在4個條件同時成立時破壞其中的任意一個條件。處理死鎖的方法包括:
該方法是為資源申請設(shè)置某些限制條件,去破壞產(chǎn)生死鎖的四個必要條件中的一個或者幾個,來預(yù)防發(fā)生死鎖。預(yù)防死鎖是一種較易實現(xiàn)的方法,已被廣泛使用。但是由于所施加的限制條件往往太嚴格,可能會導(dǎo)致系統(tǒng)資源利用率和系統(tǒng)吞吐量降低。
使用的限制條件一般有:
A.消除持有和等待這個條件:任務(wù)要一次申請完它所有需要的資源,只有當所有資源都可以獲得時它才能繼續(xù)運行。由于要求任務(wù)一次申請完其所有的所有資源,因而就不存在持有和等待這種情況。但是其不足在于:在實際的系統(tǒng)中很難預(yù)測一個任務(wù)需要那些資源,而且即便可以預(yù)測出來任務(wù)所需的資源,任務(wù)在運行時也不一定就要用到這些資源,因為運行中真正需要的資源是由代碼路徑?jīng)Q定的,這就可能造成占有了不使用的資源從而導(dǎo)致出現(xiàn)浪費;更嚴重的問題在于,使用該防范隱含著一個要求,即任務(wù)所需要的資源必須同時被釋放。這就意味著所有的資源都只能在任務(wù)已經(jīng)不需要任何資源時才能被釋放,這會造成極大的資源浪費。
B.消除不可搶占這個條件:如果任務(wù)申請新的資源的請求不能被滿足,它就應(yīng)該釋放它已經(jīng)持有的資源。隨后任務(wù)再次嘗試申請資源的時候應(yīng)該申請以前已經(jīng)持有的資源和新需要的資源。與第一種條件相比,這種條件不需要任務(wù)一次申請其所需的所有資源,而是根據(jù)需要申請。但是該方法也存在嚴重的不足,因而它在申請一種資源失敗后,就會釋放所有已經(jīng)持有的資源,當重新嘗試申請資源時就要申請這個時候所需的所有資源,這就需要追蹤所需的資源,而且在再次嘗試時,可能以前已經(jīng)被持有過的資源也變的不可用了,這無疑加大了編程的復(fù)雜度。
C.消除循環(huán)等待這個條件: 該方法要求給資源進行統(tǒng)一編號,如果任務(wù)已經(jīng)持有了編號為i的資源,則它只能申請編號大于i的資源。這就消除了循環(huán)等待這個條件。
該方法同樣是屬于事先預(yù)防的策略,但它并不須事先采取各種限制措施去破壞產(chǎn)生死鎖的的四個必要條件,而是在資源的動態(tài)分配過程中,用某種方法去防止系統(tǒng)進入不安全狀態(tài),從而避免發(fā)生死鎖。避免死鎖算法中最有代表性的算法是Dijkstra E.W 于1968年提出的銀行家算法:銀行家算法是一種最有代表性的避免死鎖的算法。在避免死鎖方法中允許任務(wù)動態(tài)地申請資源,但系統(tǒng)在進行資源分配之前,應(yīng)先計算此次分配資源的安全性,若分配不會導(dǎo)致系統(tǒng)進入不安全狀態(tài),則分配,否則等待。安全序列是指一個任務(wù)序列{P1,…,Pn}是安全的,即對于每一個任務(wù)Pi(1≤i≤n),它之后的任務(wù)所需要的資源量不超過系統(tǒng)當前剩余資源量與所有進程Pj (j < i )當前占有資源量之和。安全狀態(tài)和不安全狀態(tài):
為了使用該策略,每個任務(wù)都需要預(yù)估它所需要的最大資源量,然后系統(tǒng)使用該信息建立一個資源需求表以供使用。但是通常這種預(yù)估都是比較困難的。而且由于預(yù)估的是最大資源量,而實際運行中一個任務(wù)并不一定會真正用到完它所預(yù)估的最大資源量,因而使用這種預(yù)估進行死鎖避免時有可能導(dǎo)致不必要的阻塞。
死鎖檢測并不須事先采取任何限制性措施,它只用于在運行過程中發(fā)生死鎖。并精確地確定與死鎖有關(guān)的任務(wù)和資源,然后就可以采取適當措施,從系統(tǒng)中將已發(fā)生的死鎖清除掉。
所謂單實例資源即該資源只有1個,因此也只能被一個任務(wù)所申請使用。
所謂多實例資源即該資源有多個,因此在同一時間可能被多個任務(wù)所使用
它一般與檢測死鎖一起使用。常用的實施方法是撤銷或掛起一些任務(wù),以便回收一些資源,再將這些資源分配給已處于阻塞狀態(tài)的任務(wù),使之轉(zhuǎn)為就緒狀態(tài),以繼續(xù)運行。死鎖的檢測和解除措施,有可能使系統(tǒng)獲得較好的資源利用率和吞吐量,但在實現(xiàn)上難度也最大。
這些策略一般都是由系統(tǒng)實現(xiàn)和支持的,在應(yīng)用程序的編寫中也有一些原則可供參考:
A.不要在可能會對性能造成不良影響的長時間操作(如 I/O)中持有鎖。
B.不要在調(diào)用模塊外且可能重進入模塊的函數(shù)時持有鎖。
C.一般情況下,優(yōu)先使用粗粒度鎖,如果確定粗粒度鎖對性能造成了很大影響,再使用細粒度鎖。
D.使用多個鎖時,盡量讓所有任務(wù)都按照相同的順序來上鎖以避免死鎖。
優(yōu)先級逆轉(zhuǎn):優(yōu)先級逆轉(zhuǎn)指的是在可搶占系統(tǒng)中,高優(yōu)先級任務(wù)由于等待低優(yōu)先級任務(wù)所持有的資源而阻塞,同時低優(yōu)先級優(yōu)先運行的狀態(tài)。它的基本表現(xiàn)有兩種情形:
A.低優(yōu)先級T1任務(wù)持有資源R運行;高優(yōu)先級任務(wù)T2啟動開始運行,高優(yōu)先級任務(wù)需要使用資源R,但是無法獲得該資源,因而阻塞;低優(yōu)先級任務(wù)T1繼續(xù)運行,看上去好像高優(yōu)先級任務(wù)被低優(yōu)先級任務(wù)搶占了
B.低優(yōu)先級T1任務(wù)持有資源R運行;高優(yōu)先級任務(wù)T2啟動開始運行,高優(yōu)先級任務(wù)需要使用資源R,但是無法獲得該資源,因而阻塞;低優(yōu)先級任務(wù)T1被調(diào)度運行;此時一個優(yōu)先級小于T2但是大于T1的任務(wù)T3啟動了,它就會搶占任務(wù)T1;最終看起來好像任務(wù)T3搶 占了高優(yōu)先級任務(wù)T2,如果說情形1由于競爭資源還比較容易看出來的話,情形2則更具有迷惑性,T2和T3之間不存在競爭關(guān)系,T3竟然在T1之前運行了。
大部分情況下優(yōu)先級逆轉(zhuǎn)并不導(dǎo)致問題,因為高優(yōu)先級任務(wù)只是延遲執(zhí)行了,但是有時候這也會是個問題。
由于優(yōu)先級逆轉(zhuǎn)和資源的共享使用有關(guān),因而可以通過對資源添加訪問控制協(xié)議來解決這個問題,可以通過如下三種資源訪問控制協(xié)議來解決優(yōu)先級逆轉(zhuǎn)問題:
A.優(yōu)先級繼承協(xié)議
B.天花板優(yōu)先級協(xié)議
C.優(yōu)先級天花板協(xié)議
該協(xié)議的訪問控制規(guī)則:如果一個任務(wù)T1由于無法獲取資源R而阻塞,并且其優(yōu)先級高于資源R的持有者T2的優(yōu)先級,就提升其持有者T2的優(yōu)先級到任務(wù)T1的優(yōu)先級。具體的規(guī)則:
在天花板優(yōu)先級中,所有任務(wù)所需要的所有資源都是已知的,所有任務(wù)的優(yōu)先級也是已知的。每種資源都有一個天花板優(yōu)先級,它等于所有需要使用該資源的任務(wù)的最高優(yōu)先級。比如系統(tǒng)中有任務(wù)T1(優(yōu)先級4)、T2(優(yōu)先級6)、T3(優(yōu)先級8)、T4(優(yōu)先級10),資源R1、R2、R3、R4,其中任務(wù)T1需要使用資源R1、R3,任務(wù)T2需要使用資源R2,任務(wù)T3需要使用資源R2、R4,任務(wù)T4需要使用資源R1、R3、R4.則資源R1、R2、R3、R4的天花板優(yōu)先級分別為:10,8,10,10。使用該協(xié)議時的規(guī)則為:
類似于天花板優(yōu)先級協(xié)議,在優(yōu)先級天花板協(xié)議中所有任務(wù)所需要的所有資源都是已知的,所有任務(wù)的優(yōu)先級也是已知的。每種資源都有一個天花板優(yōu)先級,它等于所有需要使用該資源的任務(wù)的最高優(yōu)先級。比如系統(tǒng)中有任務(wù)T1(優(yōu)先級4)、T2(優(yōu)先級6)、T3(優(yōu)先級8)、T4(優(yōu)先級10),資源R1、R2、R3、R4,其中任務(wù)T1需要使用資源R1、R3,任務(wù)T2需要使用資源R2,任務(wù)T3需要使用資源R2、R4,任務(wù)T4需要使用資源R1、R3、R4.則資源R1、R2、R3、R4的天花板優(yōu)先級分別為:10,8,10,10。二者不同之處在于規(guī)則,在優(yōu)先級天花板協(xié)議中有一個當前優(yōu)先級天花板,當前優(yōu)先級天花板等于當前正被使用的所有資源的最高天花板優(yōu)先級,基于當前優(yōu)先級天花板,該協(xié)議的規(guī)則為:
該協(xié)議結(jié)合了優(yōu)先級繼承協(xié)議和天花板優(yōu)先級協(xié)議,用當前正在被使用的資源的優(yōu)先級天花板計算出了一個當前天花板優(yōu)先級,但是它又不同于運行任務(wù)的優(yōu)先級;任務(wù)的運行優(yōu)先級只有在任務(wù)阻塞了一個高優(yōu)先級任務(wù)時才會改變,而且這個改變不是簡單的設(shè)置為當前優(yōu)先級變化板,而是繼承它所阻塞的高優(yōu)先級任務(wù)的優(yōu)先級
經(jīng)常見到的一個需求是使得應(yīng)用程序只有一個運行實例在運行。這可以通過記錄鎖來實現(xiàn),實現(xiàn)方法是:
A.在啟動應(yīng)用后創(chuàng)建一個特殊文件,該文件的位置和名字是特定唯一的
B.嘗試在該文件上上一個記錄鎖寫鎖,并鎖住整個文件
C.如果上鎖失敗,說明有一個應(yīng)用實例在運行,退出
D.繼續(xù)執(zhí)行
之所以記錄鎖可以實現(xiàn)該目的是因為:根據(jù)記錄鎖的特性,無論記錄鎖的持有者進程以何種方式結(jié)束,系統(tǒng)都會自動釋放它所持有的所有記錄鎖--如果進程沒有自己釋放它的話。因而只要無法鎖定就肯定表明有一個正在運行的實例正在持有這把鎖。
由于命名信號量也具有類似的特性(系統(tǒng)會在進程終止時自動關(guān)閉其打開的所有命名信號量),因而命名信號量也可以用于該目的。
新聞熱點
疑難解答