死鎖:多個進程都被阻塞,並且一直處於這種狀態。軟硬件資源都有可能。
死鎖規範定義在 6.2
本章討論幾類死鎖,如何出現,如何防止或避免死鎖的方法。
6.1 資源
爲了更好的討論將,需要排他性使用的對象稱爲『資源』。
6.1.1 可搶佔資源和不可搶佔資源
可搶佔資源:可以從擁有它的進程中搶佔,如內存(可以頁面置換)
不可搶佔資源:不引起相關計算失敗的情況下,無法將它從其他佔有它的進程處搶佔過來。如打印機
死鎖與不可搶佔資源有關,可搶佔資源有潛在死鎖可以通過分配資源化解,所以重點討論不可搶佔資源。
使用一個資源的事件順序可以抽象如下:
- 請求資源
- 使用資源
- 釋放資源
在後面討論中假設:如果某個進程請求資源失敗,那麼它就進入休眠狀態。
6.1.2 資源獲取
這段講了例子,不好總結,信號量表示資源狀態,down 操作獲取資源,up 操作釋放資源。
6.2 死鎖簡介
死鎖規範定義如下:如果一個進程集合中的每個進程都在等待只能由該進程集合中的其他進程才能引發事件,那麼,該進程集合就是死鎖的。
資源死鎖:進程互相等待其他進程釋放資源,無法被釋放照成的死鎖
6.2.1 資源死鎖的條件
- 互斥條件。每個資源要麼已經被分配給一個進程,要麼可用
- 佔有和等待條件。已經得到了某個資源的進程可以再請求新的資源。
- 不可搶佔條件。已經被分配給一個進程的資源不能強制性地被搶佔。
- 環路等待條件。一定有至少兩個進程組成一條環路,環路中每個進程等待下個進程所佔有的資源
6.2.2 死鎖建模
用有向圖簡歷上述模型。
兩類節點:圓形表示進程,方形表示資源。
從資源節點到進程節點的有向邊代表該資源已被請求、授權並被進程佔用。
由進程節點到資源節點的有向邊代表該進程正在請求該資源,並且已經被阻塞。
資源分配圖,可以用來作分析工具,檢查是否有環即可判斷是否存在死鎖。
6.3 鴕鳥算法
最簡單的方法是沒有方法,放棄預防死鎖發生。根據頻率、嚴重性等考量。
6.4 死鎖檢測和死鎖恢復
允許死鎖發生。
6.4.1 每種類型一個資源的死鎖檢測
每種資源類型只有一個資源。
介紹了一個檢測資源分配圖是否存在環的算法。
6.4.2 每種類型多個資源的死鎖檢測
這塊沒看懂
好像是說銀行家算法,找到可運行的,運行,釋放,最後剩的就是死鎖。
但是這樣好像不能多個進程同時運行,同時運行的話進程之間執行指令不確定,判死鎖有點問題,感覺少了。
網上看個銀行家算法就略過這
什麼時候檢測進程?
每次資源請求時,代價高
每隔一段時間或 CPU 使用率低時。沒講缺點,但應該感覺不及時也不太行。
6.4.3 從死鎖中恢復
1. 利用搶佔恢復
需要資源本身特性的支持。
2. 利用回滾恢復
檢查點檢查:將進程的狀態寫入一個文件以備以後重啓
檢測到死鎖,將擁有所需要資源的進程進行回滾。
3. 通過直接殺死進程
直接殺死某些進程,解決死鎖。最好殺死重新執行後不會影響結果的進程。
6.5 死鎖避免
6.5.1 資源軌跡圖
6.5.2 安全狀態和不安全狀態
安全狀態:存在某種調度次序能夠使每個進程都運行完畢
不安全狀態不代表死鎖,從安全狀態出發能保證所有進程完成,而不安全狀態不能保證。
6.5.3 單個銀行家算法
銀行家算法:避免死鎖的調度算法
對每一個請求進行檢查,如果滿足這一請求會到達安全狀態就滿足,否則推遲請求。
6.5.4 多個資源的銀行家算法
思想和單個銀行家算法一樣,只不過資源變多。
該算法缺乏實用價值。因爲很少有進程能夠運行前就知道其所需資源最大值。而且進程數不是固定不變的。而且原本可用資源可能也會變成不可用。
6.6 死鎖預防
死鎖避免從本質上來說不可能。
6.6.1 破壞互斥條件
比如打印機被多個進程同時使用會混亂。通過假脫機打印機技術,可以使若干進程同時產生輸出,真正請求物理打印機的進程是打印機守護進程,由於守護進程絕不請求別的資源,所以不會因打印機產生死鎖。
6.6.2 破壞佔有並等待條件
規定所有進程在開始執行前請求所需的全部資源,如果所需全部資源可用,那麼就將它們分配給這個進程。
缺點多,如果知道需要哪些進程可以銀行家算法;資源利用率不高,可能某個資源等待另個資源,但同時被申請了。
另種方案,當一個進程請求資源,先暫停釋放當前佔用的所有資源,再嘗試一次獲取所有所需資源。
6.6.3 破壞不可搶佔條件
通過資源虛擬化,但是不是所有資源都可以虛擬化。
6.6.4 破壞環路等待條件
一種方案,保證每個進程任何時刻只能佔用一個資源,這個限制不可接受。
另一種方案,將所有資源統一編號,進程提出資源請求需要滿足資源編號順序(如升序)提出。差不多就定義一個拓撲序,所以無環。
另一變種,第二種的請求限制改爲,不允許進程請求比當前所佔有資源編號低的資源。還是無環圖
這兩種方案找不出使每個人都滿意的編號次序,編號越大限制越多。
6.7 其他問題
6.7.1 兩階段加鎖
第一階段對所需資源請求加鎖,加鎖成功執行第二階段,然後釋放鎖;加鎖失敗,釋放第一階段加鎖記錄,然後重新加鎖。
該方法並不通用。
6.7.2 通信死鎖
通信死鎖:沒有完全可見的資源,每個進程因爲等待另外一個進程事件而產生的死鎖。
有一種技術通常可以中斷通信死鎖:超時
都快到計網TCP了。。
6.7.3 活鎖
進程同時請求發現無法使用,繼續一段時間,然後同時釋放。
一種解決方法,可以使等待時間隨機,這樣就不會同步了。
6.7.4 飢餓
某個進程一直(很久)無法佔用資源,比較常見於優先級調度中。感覺可以整個老化算法解決。