死鎖
死鎖,它是操作系統或軟件運行的一種狀態:在多任務下,當一個或多個進程等待系統資源而資源又被系統本身或其它進程占用時,就形
成了死鎖。
死鎖發生的最常見形式是兩個或多個線程等待被另一個線程占用的資源:
如果兩個順序同時發生,線程1將永遠無法獲得鎖B,因為鎖B被線程2占有。同時線程2也永遠無法獲得鎖A,因為鎖A被線程1擁有。
死鎖產生的條件
死鎖的發生必須具備以下四個條件:
①互斥條件:指進程對所分配到的資源進行排它性使用,即在一段時間內某資源只被一個進程占用。如果此時還有其它進程請求資源,則
請求者只能等待,直到占有資源的進程用完釋放。
②請求和保持條件:指進程已經保持至少一個資源,但又提出了新的資源請求,而該資源已被其他進程占用,此時請求進程阻塞,但又對
自己已獲得的資源保持不放。
③不剝奪條件:指進程已獲得的資源,在使用結束之前,不能被剝奪,只能在使用結束之后自己釋放。
④環路等待條件:指在發生死鎖時,必然存在一個進程——資源的環形鏈,即進程集合{P0,P1,…,Pn}中的P0正在等待一個P1占用的
資源,P1正在等待P2占用的資源,……,Pn正在等待P0占用的資源。
如何避免和處理死鎖
預防死鎖:預防死鎖的方法是使四個條件中的第二、三、四個條件之一不能成立,來避免發生死鎖。
①加鎖順序:按同一順序加鎖。
當多個進程需要相同的多個鎖,又按照不同的順序加鎖時,就很容易發生死鎖。如果能保證所有的進程都按照相同的順序獲得鎖,那么死
鎖就不會產生。
②加鎖時限:進程嘗試獲取鎖時加上一定的時限。
也就是說如果申請鎖時超過了這個時限,該進程就放棄對該鎖的請求,并釋放所有已經獲得的鎖。然后過一 段隨機的時間后重試。這段
隨機的時間讓其它線程有機會嘗試獲取相同的鎖,并且讓該應用在沒有獲得鎖的時候繼續進行。
問題是,如果有非常多的進程同一時間去競爭同一批資源,即使有超時和回退機制,還是可能會存在某些進程反復嘗試卻始終得不到鎖的
問題。
避免死鎖:該方法是同樣是屬于事先預防的策略,但它并不須事先采取各種限制措施去破壞產生死鎖的四個必要條件,而是在資源的動態
分配過程中,用某種方法去防止系統進入不安全狀態,從而避免發生死鎖。
死鎖檢測:它主要針對那些無法實現按序加鎖并且加鎖時限也不可行的情況。
通過設置的檢測機構,及時地檢測出死鎖的發生,并精確地確定與死鎖有關的進程和資源。然后采取適當措施從系統中將已發生的死鎖清
除掉。
每當一個進程獲得了鎖,會在進程和鎖的相關數據結構中將其記下。并且,每當有進程請求鎖,都會記錄在這個數據結構中。當
一個進程請求鎖失敗時,該線程可以遍歷進程和鎖的數據結構確認是否發生死鎖。
例如:
進程A請求鎖2,但鎖2倍進程B占有,于是進程A等待進程B。同理,進程B等待進程C,進程C等待進程D,進程D等待進程A。進程
A為了檢測死鎖,它需要遞進地檢測所有被B請求的鎖。從進程B請求的所開始,進程A找到了進程C,然后找到了進程D。發現進程D請
求的鎖被進程A自己所占有,這樣檢測到發生了死鎖。
當進程A檢測到發生死鎖之后,一個可行的方法是進程A釋放自己占有的鎖,回退,然后經過一段隨機的時間后重試。這和加鎖時限相
似,不同是死鎖已經發生了。
死鎖解除:這是與檢測死鎖相配套的一種措施。
當發現有進程死鎖時,應立即把它們從死鎖狀態中解脫出來。
一種方法是,剝奪資源。從其它進程剝奪足夠數量的資源給死鎖進程,以解除死鎖狀態。
還有一種方法是,撤銷進程。最簡單的撤銷進程的方法是使全部死鎖進程都夭折掉;稍微溫和一點的方法是按照某種順序逐個地撤銷進
程,這只有足夠的資源可用。
推薦教程:PHP視頻教程
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com