文章目錄
- 一、什么是死鎖?
- 死鎖產生的原因?
- 死鎖產生的必要條件?
- 互斥條件
- 請求并保持
- 不可剝奪
- 環路等待
- 二、處理死鎖的基本方法
- 死鎖的預防
- 摒棄請求和保持條件
- 摒棄不可剝奪條件
- 摒棄環路等待條件
- 死鎖的避免
- 銀行家算法案例
提示:以下是本篇文章正文內容,下面案例可供參考
一、什么是死鎖?
由于多個進程(兩個及以上)競爭共享資源而引起進程不能向前推進的僵死狀態被稱為死鎖。
死鎖產生的原因?
進程訪問資源按照申請資源、訪問資源、釋放資源的順序來執行,如果出現競爭共享資源且分配資源的順序不當時,則可能會產生死鎖。
死鎖產生的必要條件?
互斥條件
當一個進程訪問某個共享資源時,其他進程不能訪問該共享資源。如果當前某個共享資源正在被進程訪問,則其他進程想要對該共享資源進行訪問時,必須要把請求該共享資源的進程阻塞起來,直到資源被當前所擁有進程釋放。
請求并保持
進程已經保持擁有了至少一個資源,又提出了申請新資源的要求,而新申請的資源已經被其他進程所占用,此時進程就會陷入阻塞狀態,但又對自己所擁有的資源保持不釋放,使得其他進行無法訪問該進程所保持的資源。
不可剝奪
進程已經獲取的資源不能被其他進程所剝奪,只能由自己釋放。
環路等待
在發生死鎖時,必然存在一個進程申請資源的環形鏈,即進程集合{p0,p1,p2,p3…}中,p0等待獲取p1占用的一個資源,p1等待獲取p2占用的一個資源,p2等待p3…,最總pn等到獲取p0所占用資源,此時形成一個環形閉環。
二、處理死鎖的基本方法
處理死鎖的基本方法有預防死鎖、避免死鎖、檢測并解除死鎖、忽略死鎖問題等。為確保不發生死鎖,操作系統可以采用死鎖預防和死鎖避免方案。
死鎖的預防
死鎖的預防是根據死鎖的必要條件來進行處理,即當不滿足死鎖成立的四個必要條件(互斥條件、請求并保持、不可剝奪、環形等待)中的一個,即死鎖無法形成。需要明確的是在操作系統中,無法預知進程是否訪問某個臨界資源,所以通常不能采用擯棄互斥條件
來預防死鎖的發生,因此死鎖的預防可以從剩下來的三個條件入手。
摒棄請求和保持條件
可以通過摒棄請求和保持條件來預防死鎖。摒棄請求和保持條件的一種方法即:
系統要求所有進程一次性地申請在整個運行過程中所需要的全部資源,如果其中存在一個資源申請不成功,則其他資源也不分配給該進程,該進程進入阻塞狀態。也就是在運行前將所有需要資源一次性進行申請鎖定,后續運行過程中將不再像外部申請其他資源。
摒棄不可剝奪條件
可以通過摒棄不可剝奪條件來預防死鎖。摒棄不可剝奪條件即:
一個已保持某些資源的進程,當它再次提出申請新的資源時,如果不能立刻得到滿足,必須釋放自身所擁有的所有資源。這種方法的缺點是實現復雜、代價高。
摒棄環路等待條件
摒棄環路等待條件即:
進程必須按照規定的順序申請資源,對所有不同類型的資源進行排序,要求每個進程按照規定順序申請資源。
缺點:
1.系統為資源分配的順序可能與進程實際使用資源的順序不同。
2.在編碼實現復雜
死鎖的避免
銀行家算法是一種避免死鎖的資源分配和調度算法,由Edsger Dijkstra 在 1965 年提出。用于操作系統中資源的管理,確保系統不會進入死鎖狀態。基本思想是通過模擬資源預分配,確保系統在任何時候都能滿足至少一個進程所需的最大資源,從而避免死鎖。 銀行家算法主要包括以下幾個步驟:
- 初始資源類型以及數量,并初始化每個進程所需最大資源數量,當前分配資源數量、當前資源可用剩余量。
- 安全性檢查:檢查當前系統是否存于安全性狀態。
- 資源請求:當一個進程請求資源時,首先檢查進程請求資源是否超出該進程最大資源數量,如果請求的某個資源大于該進程所需該資源的最大數量,則拒絕請求。否則系統嘗試為該進程分配資源,并更新狀態是否安全。
銀行家算法案例
假設當前存在5個進程,同個需要申請三種不同類型的資源A\B\C,資源A一共有10個,資源B共有5個,資源C共有7個。
- 假設p0進程對資源A\B\C最大需求為7,5,3,當前已經分配A\B\C資源為0,1,0,因此p0進程還需要分配A\B\C資源個數為7,4,3。
- 假設p1進程對資源A\B\C最大需求為3,2,2,當前已經分配A\B\C資源為2,0,0,因此p1進程還需要分配A\B\C資源個數為1,2,2。
- 假設p2進程對資源A\B\C最大需求為9,0,2,當前已經分配A\B\C資源為3,0,2,因此p2進程還需要分配A\B\C資源個數為6,0,0。
- 假設p3進程對資源A\B\C最大需求為2,2,2,當前已經分配A\B\C資源為2,1,1,因此p3進程還需要分配A\B\C資源個數為0,1,1。
- 假設p4進程對資源A\B\C最大需求為4,3,3,當前已經分配A\B\C資源為0,0,2,因此p4進程還需要分配A\B\C資源個數為4,3,1。
這里要記住公式: Need(需求)= Max(所需最大)-Alloc(已經分配);Avail(可用數量)= 總數-Alloc(已經分配)
各資源總數A:10, B:5,C:7.
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0 | 0 1 0 | 7 5 3 | 7 4 3 | |
p1 | 2 0 0 | 3 2 2 | 1 2 2 | |
p2 | 3 0 2 | 9 0 2 | 6 0 0 | |
p3 | 2 1 1 | 2 2 2 | 0 1 1 | |
p4 | 0 0 2 | 4 3 3 | 4 3 1 |
通過Alloc已分配的A、B、C資源進行總和,可以計算出當前A資源已經分配了7個,B類資源已經分配了2個,C類資源已經分配了5個,因此A、B、C資源剩余可分配數量分別為3:3:2。Avail(可用數量)= 總數-Alloc(已經分配)
因此我們可以從p0~p4進行匹配,可以發現p0還需要資源分別為7:4:3,而現在剩余資源3:3:2并不滿足條件,因此拒絕向p0分配資源。而p1所需資源1:2:2可以被剩余可分配資源滿足,因此嘗試將資源分配給進程p1,分配圖更新后如下:
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0 | 0 1 0 | 7 5 3 | 7 4 3 | |
p1 | 3 2 2 | 3 2 2 | 0 0 0 | 2 1 0 |
p2 | 3 0 2 | 9 0 2 | 6 0 0 | |
p3 | 2 1 1 | 2 2 2 | 0 1 1 | |
p4 | 0 0 2 | 4 3 3 | 4 3 1 |
當可剩余資源分配給p1進程運行完成后,p1將會把所擁有資源釋放,因此A、B、C資源的數量變為 5:3:2。
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0 | 0 1 0 | 7 5 3 | 7 4 3 | |
p1(執行完成) | 0 0 0 | 3 2 2 | 0 0 0 | 5 3 2 |
p2 | 3 0 2 | 9 0 2 | 6 0 0 | |
p3 | 2 1 1 | 2 2 2 | 0 1 1 | |
p4 | 0 0 2 | 4 3 3 | 4 3 1 |
現在再次嘗試進行新的一輪分配,p0、p2進程所需資源大于當前可分配資源,因此拒絕分配;而p3進程滿足條件,因此嘗試將資源分配給進程p3,分配圖更新后如下:
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0 | 0 1 0 | 7 5 3 | 7 4 3 | |
p1(執行完成) | 0 0 0 | 3 2 2 | 0 0 0 | |
p2 | 3 0 2 | 9 0 2 | 6 0 0 | |
p3 | 2 2 2 | 2 2 2 | 0 0 0 | 5 2 1 |
p4 | 0 0 2 | 4 3 3 | 4 3 1 |
當可剩余資源分配給p3進程運行完成后,p3將會把所擁有資源釋放,因此A、B、C資源的數量變為 7:4:3。
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0 | 0 1 0 | 7 5 3 | 7 4 3 | |
p1(執行完成) | 0 0 0 | 3 2 2 | 0 0 0 | |
p2 | 3 0 2 | 9 0 2 | 6 0 0 | |
p3(執行完成) | 0 0 0 | 2 2 2 | 0 0 0 | 7 4 3 |
p4 | 0 0 2 | 4 3 3 | 4 3 1 |
現在再次嘗試進行新的一輪分配,p0進程所需資源恰好等于當前可分配資源,因此嘗試將資源分配給進程p0,分配圖更新后如下:
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0 | 7 5 3 | 7 5 3 | 7 4 3 | 0 0 0 |
p1(執行完成) | 0 0 0 | 3 2 2 | 0 0 0 | |
p2 | 3 0 2 | 9 0 2 | 6 0 0 | |
p3(執行完成) | 0 0 0 | 2 2 2 | 0 0 0 | |
p4 | 0 0 2 | 4 3 3 | 4 3 1 |
當可剩余資源分配給p0進程運行完成后,p0將會把所擁有資源釋放,因此A、B、C資源的數量變為 7:5:3。
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0(執行完成) | 0 0 0 | 7 5 3 | 0 0 0 | 7 5 3 |
p1(執行完成) | 0 0 0 | 3 2 2 | 0 0 0 | |
p2 | 3 0 2 | 9 0 2 | 6 0 0 | |
p3(執行完成) | 0 0 0 | 2 2 2 | 0 0 0 | |
p4 | 0 0 2 | 4 3 3 | 4 3 1 |
現在再次嘗試進行新的一輪分配,當前可分配資源滿足p2進程所需資源,因此嘗試將資源分配給進程p2,分配圖更新后如下:
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0(執行完成) | 0 0 0 | 7 5 3 | 0 0 0 | |
p1(執行完成) | 0 0 0 | 3 2 2 | 0 0 0 | |
p2 | 9 0 2 | 9 0 2 | 0 0 0 | 1 5 3 |
p3(執行完成) | 0 0 0 | 2 2 2 | 0 0 0 | |
p4 | 0 0 2 | 4 3 3 | 4 3 1 |
當可剩余資源分配給p2進程運行完成后,p2將會把所擁有資源釋放,因此A、B、C資源的數量變為 10:5:5。
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0(執行完成) | 0 0 0 | 7 5 3 | 0 0 0 | |
p1(執行完成) | 0 0 0 | 3 2 2 | 0 0 0 | |
p2(執行完成) | 0 0 0 | 9 0 2 | 0 0 0 | 10 5 5 |
p3(執行完成) | 0 0 0 | 2 2 2 | 0 0 0 | |
p4 | 0 0 2 | 4 3 3 | 4 3 1 |
現在再次嘗試進行新的一輪分配,當前可分配資源滿足p4進程所需資源,因此嘗試將資源分配給進程p4,分配圖更新后如下:
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0(執行完成) | 0 0 0 | 7 5 3 | 0 0 0 | |
p1(執行完成) | 0 0 0 | 3 2 2 | 0 0 0 | |
p2(執行完成) | 0 0 0 | 9 0 2 | 0 0 0 | |
p3(執行完成) | 0 0 0 | 2 2 2 | 0 0 0 | |
p4 | 4 3 3 | 4 3 3 | 0 0 0 | 6 2 4 |
當可剩余資源分配給p4進程運行完成后,p4將會把所擁有資源釋放,因此A、B、C資源的數量變為 10:5:7。
進程名稱 | Alloc(A B C) | Max(A B C) | Need(A B CC) | Avail(A B C) |
---|---|---|---|---|
p0(執行完成) | 0 0 0 | 7 5 3 | 0 0 0 | |
p1(執行完成) | 0 0 0 | 3 2 2 | 0 0 0 | |
p2(執行完成) | 0 0 0 | 9 0 2 | 0 0 0 | |
p3(執行完成) | 0 0 0 | 2 2 2 | 0 0 0 | |
p4(執行完成) | 0 0 0 | 4 3 3 | 0 0 0 | 10 5 7 |
因此資源分配進程順序可以是P1->P3->P0->P2->P4。