文章目錄
哲學家就餐問題
描述
五個哲學家圍着一張圓桌,每個哲學家面前放着食物。哲學家的生活有兩種交替活動:喫飯以及思考。
當一個哲學家喫飯時,需要先拿起自己左右兩邊的兩根筷子,並且一次只能拿起一根筷子。
如果哲學家同時拿起左手邊的筷子,那麼就無法拿起右手邊的筷子,造成死鎖。
#define N 5
void philosopher(int i) {
while(TRUE) {
think();
P(i); // 拿起左邊的筷子
P((i+1)%N); // 拿起右邊的筷子
eat();
V(i);
V((i+1)%N);
}
}
操作系統中的死鎖是指多個進程在運行過程中因爲爭奪資源造成的一種相互等待的情況。
死鎖必要條件
如果一個系統中下面四個條件同時滿足,那麼會引起引起死鎖。
- 互斥:至少有一個資源處於非共享模式,即一次只有一個進程使用,如果另一個進程申請該資源,那麼申請進程必須等到該資源被釋放爲止。
- 佔有並等待:一個進程必須佔有至少一個資源,並等待另一資源,而該資源爲其他進程所佔有。
- 非搶佔:資源不能被搶佔,即資源只能在進程完成任務後自動釋放。
- 環路等待:有兩個或者兩個以上的進程組成一條環路,該環路中的每個進程都在等待下一個進程所佔有的資源。
死鎖處理方法
鴕鳥策略
鴕鳥策略是指不採取任何措施。
大多數操作系統,包括 Unix,Linux 和 Windows,處理死鎖問題的辦法都是鴕鳥策略,即忽略它。
死鎖檢測與死鎖恢復
不試圖阻止死鎖,而是當檢測到死鎖發生時,採取措施進行恢復。
每種類型一個資源的死鎖情況
上圖是資源分配圖,其中方框表示資源。
圓圈表示進程。資源指向該進程表示該資源已經分配給該進程,進程指向資源表示進程請求獲取該資源。
b是抽取出來的環,他滿足了環路等待的條件,因此會發生死鎖。
死鎖檢測算法是通過檢測有向圖是否存在環來實現,從一個節點出發進行深度優先搜索,對訪問過的節點進行標記,如果訪問了已經標記的節點,就表示有向圖存在環,也就是檢測到死鎖的發生。
每個類型多個資源的死鎖檢測
上圖有三個進程、四個資源。
各數據含義
- E向量代表資源總量
- A向量代表資源剩餘量
- C矩陣代表每個進程擁有的資源數量
- R矩陣代表每個進程請求的資源數量
算法描述
- 進程P1、P2所請求的資源都得不到滿足,只有進程3可以,讓進程P3執行,之後釋放P3擁有的資源。
- 此時A=(2 2 2 0)。P2可以執行,執行後釋放P2擁有的資源,A=(4 2 2 1)。
- P1也可以執行。所有進程都可以順利執行,沒有死鎖。
算法總結
每個進程開始都不被標記,執行過程中可能被標記。
當算法結束時,任何沒有被標記的進程都是死鎖進程。
- 尋找一個沒有標記的進程P1,它所請求的資源小於等於A。
- 如果找到了這樣的進程,那麼將C矩陣的第i行向量加到A中,標記該進程,並重復1。
- 知道沒有這樣的進程,算法終止。
死鎖恢復
- 利用回滾恢復——進程回退策略,即讓參與死鎖的進程回退到沒有發生死鎖前某一點處,並由此點處繼續執行,以求再次執行時不再發生死鎖。
- 通過殺死進程恢復
死鎖預防
死鎖的預防即不允許死鎖的發生,可以從破除死鎖發生的四個必要條件入手。因爲如果不具備上述四個必要條件,那麼死鎖就一定不會發生。
破壞互斥條件
通常不能通過否定互斥條件來預防死鎖
破壞佔有和等待條件
一種實現方式是所有進程在開始執行前請求所需要的全部資源。
破壞不可搶佔條件
如果一個進程所請求的資源被另一進程佔有,使它可以搶佔另一進程佔有的資源。
破壞環路
對資源進行排序,即每個進程訪問資源的順序是固定的。
舉例
進程PA,使用資源的順序是R1,R2; 進程PB,使用資源的順序是R2,R1;若採用動態分配有可能形成環路條件,造成死鎖。
採用有序資源分配法:R1的編號爲1,R2的編號爲2。
PA:申請次序應是:R1,R2
PB:申請次序應是:R1,R2
這樣就破壞了環路條件,避免了死鎖的發生。
死鎖避免
避免死鎖同樣是屬於事先預防的策略,但並不是事先釆取某種限制措施破壞死鎖的必要條件,而是在資源動態分配過程中,防止系統進入不安全狀態,以避免發生死鎖。
安全狀態
安全狀態是指系統能按某個順序爲每個進程分配資源並能避免死鎖,那麼系統狀態就是安全的。
解釋
- 第二列Has表示已擁有的資源數
- 第三列Max表示總共需要的資源數
- Free表示還有可以使用的資源數
對於上圖
- 由a出發,讓B進程擁有所需的所有資源,free變爲1,成爲圖b,運行結束,釋放B的資源,free變爲5,成爲圖c。
- 接着以同樣的形式運行C和A,使得所有進程都能成功運行。
- 所以圖a的狀態是安全的。
定義:即使所有進程突然請求對資源的最大請求,也仍然存在某種調度次序,能使每一個進程運行完畢,則稱該狀態是安全的。
單個資源的銀行家算法
描述
一個銀行家,他向一羣客戶分別承諾一定的貸款額度,算法要求做的是,判斷對請求的滿足是否會進入不安全狀態,如果是,就拒絕請求;否則就予以分配。
比如上圖中c就是不安全的狀態,因此算法會拒絕之前的請求,從而避免進入圖c中的狀態。
解釋一下
圖b中,可以先把free的2個資源給C,然後C釋放資源,free變爲4,然後再分給B,接着,分給A,最後分給D,這樣是安全狀態。
而如果圖b將一個free的資源分給了b,free變爲1,這時不管再將free的1個資源給誰都不會達到最大的資源請求,從而導致了死鎖。
多個資源的銀行家算法
解釋
- 上圖有五個進程,四個資源
- 左邊表示已經分配的資源,右邊表示已經分配的資源。
- E、P、A代表總資源、已分配資源、可用資源(A=1/0/2/0 代表剩餘的四個資源的數量)
算法描述
- 查找右邊的矩陣是否存在一行小於等於向量A,如果沒有那麼系統將會發生死鎖。狀態不安全
- 如果找到,將該進程標記爲終止,並將它的資源加到A中。
- 重複上述兩步,直到所有標記都標爲終止,則狀態是安全的。
如果一個狀態是不安全的,就拒絕進入這個狀態。
參考
https://blog.csdn.net/sunmc1204953974/article/details/46559589
https://blog.csdn.net/weiyongle1996/article/details/71511956
http://c.biancheng.net/cpp/html/2606.html