一坝冕、什么是死鎖
所謂死鎖欢峰,是指多個進(jìn)程循環(huán)等待它方占有的資源而無限期地僵持下去的局面。
二坑夯、產(chǎn)生死鎖的必要條件
- 互斥條件
即某個資源在一段時間內(nèi)只能由一個進(jìn)程占有岖寞,不能同時被兩個或兩個以上的進(jìn)程占有 - 請求與保持條件
進(jìn)程至少已經(jīng)占有一個資源,但又申請新的資源渊涝;由于該資源已被另外進(jìn)程占有慎璧,此時該進(jìn)程阻塞;但是跨释,它在等待新資源之時胸私,仍繼續(xù)占用已占有的資源。 - 不剝奪條件
進(jìn)程所獲得的資源在未使用完畢之前鳖谈,資源申請者不能強行地從資源占有者手中奪取資源岁疼,而只能由該資源的占有者進(jìn)程自行釋放。 - 循環(huán)等待條件
若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系缆娃。例如存在一個進(jìn)程等待序列{P1捷绒,P2,...贯要,Pn}暖侨,其中P1等待P2所占有的某一資源,P2等待P3所占有的某一源崇渗,......字逗,而Pn等待P1所占有的的某一資源,形成一個進(jìn)程循環(huán)等待環(huán)宅广。
三葫掉、解決死鎖的方法
一般地末盔,解決死鎖的方法分為死鎖的預(yù)防修陡,避免宙攻,檢測與恢復(fù)三種(注意:死鎖的檢測與恢復(fù)是一個方法)拍顷。
1 死鎖預(yù)防
死鎖的預(yù)防是保證系統(tǒng)不進(jìn)入死鎖狀態(tài)的一種策略。它的基本思想是要求進(jìn)程申請資源時遵循某種協(xié)議籽暇,從而打破產(chǎn)生死鎖的四個必要條件中的一個或幾個洞拨,保證系統(tǒng)不會進(jìn)入死鎖狀態(tài)罢浇。
(1)打破互斥條件
即允許進(jìn)程同時訪問某些資源关翎。但是扛门,有的資源是不允許被同時訪問的,像打印機等等笤休,這是由資源本身的屬性所決定的。所以症副,這種辦法并無實用價值店雅。
(2)打破不可搶占條件
即允許進(jìn)程強行從占有者那里奪取某些資源政基。就是說,當(dāng)一個進(jìn)程已占有了某些資源闹啦,它又申請新的資源沮明,但不能立即被滿足時,它必須釋放所占有的全部資源窍奋,以后再重新申請荐健。它所釋放的資源可以分配給其它進(jìn)程。這就相當(dāng)于該進(jìn)程占有的資源被隱蔽地強占了琳袄。這種預(yù)防死鎖的方法實現(xiàn)起來困難江场,會降低系統(tǒng)性能。
(3)打破請求與保持條件
可以實行資源預(yù)先分配策略窖逗,即進(jìn)程在運行前一次性地向系統(tǒng)申請它所需要的全部資源址否。如果某個進(jìn)程所需的全部資源得不到滿足,則不分配任何資源碎紊,此進(jìn)程暫不運行佑附。只有當(dāng)系統(tǒng)能夠滿足當(dāng)前進(jìn)程的全部資源需求時,才一次性地將所申請的資源全部分配給該進(jìn)程仗考。由于運行的進(jìn)程已占有了它所需的全部資源音同,所以不會發(fā)生占有資源又申請資源的現(xiàn)象,因此不會發(fā)生死鎖秃嗜。但是权均,這種策略也有如下缺點:
在許多情況下,一個進(jìn)程在執(zhí)行之前不可能知道它所需要的全部資源痪寻。這是由于進(jìn)程在執(zhí)行時是動態(tài)的螺句,不可預(yù)測的;
資源利用率低橡类。無論所分資源何時用到蛇尚,一個進(jìn)程只有在占有所需的全部資源后才能執(zhí)行。即使有些資源最后才被該進(jìn)程用到一次顾画,但該進(jìn)程在生存期間卻一直占有它們取劫,造成長期占著不用的狀況。這顯然是一種極大的資源浪費研侣;
降低了進(jìn)程的并發(fā)性谱邪。因為資源有限,又加上存在浪費庶诡,能分配到所需全部資源的進(jìn)程個數(shù)就必然少了惦银。
(4)打破循環(huán)等待條件
實行資源有序分配策略。采用這種策略,即把資源事先分類編號扯俱,按號分配书蚪,使進(jìn)程在申請,占用資源時不會形成環(huán)路迅栅。所有進(jìn)程對資源的請求必須嚴(yán)格按資源序號遞增的順序提出殊校。進(jìn)程占用了小號資源,才能申請大號資源读存,就不會產(chǎn)生環(huán)路为流,從而預(yù)防了死鎖。這種策略與前面的策略相比让簿,資源的利用率和系統(tǒng)吞吐量都有很大提高敬察,但是也存在以下缺點:
限制了進(jìn)程對資源的請求,同時給系統(tǒng)中所有資源合理編號也是件困難事拜英,并增加了系統(tǒng)開銷静汤;
為了遵循按編號申請的次序,暫不使用的資源也需要提前申請居凶,從而增加了進(jìn)程對資源的占用時間虫给。
2 死鎖避免——銀行家算法
這是一個著名的避免死鎖的算法,是由Dijstra首先提出來并加以解決的侠碧。
例如:有三個客戶C1抹估,C2,C3弄兜,向銀行家借款药蜻,該銀行家的資金總額為10個資金單位,其中C1客戶要借9各資金單位替饿,C2客戶要借3個資金單位语泽,C3客戶要借8個資金單位,總計20個資金單位视卢。某一時刻的狀態(tài)如圖所示踱卵。
對于a圖的狀態(tài),按照安全序列的要求据过,我們選的第一個客戶應(yīng)滿足該客戶所需的貸款小于等于銀行家當(dāng)前所剩余的錢款惋砂,可以看出只有C2客戶能被滿足:C2客戶需1個資金單位,小銀行家手中的2個資金單位绳锅,于是銀行家把1個資金單位借給C2客戶西饵,使之完成工作并歸還所借的3個資金單位的錢,進(jìn)入b圖鳞芙。同理眷柔,銀行家把4個資金單位借給C3客戶期虾,使其完成工作,在c圖中驯嘱,只剩一個客戶C1彻消,它需7個資金單位,這時銀行家有8個資金單位宙拉,所以C1也能順利借到錢并完成工作。最后(見圖d)銀行家收回全部10個資金單位丙笋,保證不賠本谢澈。那麼客戶序列{C1,C2御板,C3}就是個安全序列锥忿,按照這個序列貸款,銀行家才是安全的怠肋。否則的話敬鬓,若在圖b狀態(tài)時,銀行家把手中的4個資金單位借給了C1笙各,則出現(xiàn)不安全狀態(tài):這時C1钉答,C3均不能完成工作,而銀行家手中又沒有錢了杈抢,系統(tǒng)陷入僵持局面数尿,銀行家也不能收回投資。
同理可得惶楼,下圖中安全序列為:{P1,P4,P3,P2,P0}或{P1,P4,P3,P0,P2}
3 死鎖檢測及恢復(fù)
死鎖檢測是一個更好的死鎖預(yù)防機制右蹦,它主要是針對那些不可能實現(xiàn)按序加鎖并且鎖超時也不可行的場景。
一般采用資源分配圖以及進(jìn)程請求資源圖來進(jìn)行死鎖的檢測歼捐。
下面是一幅關(guān)于四個線程(A,B,C和D)之間鎖占有和請求的關(guān)系圖何陆。像這樣的數(shù)據(jù)結(jié)構(gòu)就可以被用來檢測死鎖。
線程A等待線程B豹储,線程B等待線程C贷盲,線程C等待線程D,線程D又在等待線程A颂翼。線程A為了檢測死鎖晃洒,它需要遞進(jìn)地檢測所有被B請求的鎖。從線程B所請求的鎖開始朦乏,線程A找到了線程C球及,然后又找到了線程D,發(fā)現(xiàn)線程D請求的鎖被線程A自己持有著呻疹。這是它就知道發(fā)生了死鎖吃引。
那么當(dāng)檢測出死鎖時,這些線程該做些什么呢?
最簡單镊尺,最常用的方法就是進(jìn)行系統(tǒng)的重新啟動朦佩,不過這種方法代價很大,它意味著在這之前所有的進(jìn)程已經(jīng)完成的計算工作都將付之東流庐氮,包括參與死鎖的那些進(jìn)程语稠,以及未參與死鎖的進(jìn)程。
釋放所有鎖弄砍,回退仙畦,并且等待一段隨機的時間后重試。
一個更好的方案是給這些線程設(shè)置優(yōu)先級音婶,讓一個(或幾個)線程回退慨畸,剩下的線程就像沒發(fā)生死鎖一樣繼續(xù)保持著它們需要的鎖。如果賦予這些線程的優(yōu)先級是固定不變的衣式,同一批線程總是會擁有更高的優(yōu)先級寸士。為避免這個問題,可以在死鎖發(fā)生的時候設(shè)置隨機的優(yōu)先級碴卧。