一、系統模型
1、資源概念
- 資源一旦是被使用狀態,則其他的進程就不應該運用這個資源,有互斥性,如果沒有互斥性,就不會產生死鎖。
- 進程使用資源的有限的,資源恢復到空閒的情況。
2. 可重複使用的資源
- 在一個時間只能一個進程使用且不能刪除
- 進程獲得資源,後來釋放有其他進程重用
- 處理器,io通道,主和副存儲器,設備和數據結構,如文件,數據庫和信號量都可以看作是資源的一種形式
- 如果每個進程擁有一個資源並且請求其他資源,死鎖可能發生
3. 如何使用資源
- 創建和銷燬,進行資源管理,內存管理
- 在I/O緩衝區中的中斷,信號,消息,信息
- 如果接收消息阻塞可能會發生死鎖
- 可能少見的組合事件會引起死鎖
- 存在進程管理和調度的過程
二、死鎖的特徵及處理辦法
1. 死鎖的特徵
死鎖可能出現如果四個條件同時成立:
- 互斥:在一個時間只能有一個進程使用資源
- 持有並等待:進程保持至少一個資源正在等待獲取其他進程持有的額外資源
- 無搶佔:一個資源只能被進程自願釋放
- 循環等待:存在等待進程集合,一個等待另一個佔用的資源,首尾相接(有環)。
出現這四個條件不一定出現死鎖,但是死鎖肯定會出現這四個條件。
2. 死鎖處理辦法
方法一:確保系統永遠不會進入死鎖狀態
- 操作系統的功能會被限制,應用系統無法重複的利用cpu執行開銷也很大
方法二:運行系統進入死鎖狀態,然後恢復
- 但是判斷死鎖的開銷非常大
方法三:忽略這個問題,假裝系統中從來沒有發生死鎖;用於絕大多數的操作系統。
- 靠假設來忽略這個問題,實際操作的常用方法
包括以下四種方法:
- 死鎖預防
- 死鎖避免
- 死鎖檢測
- 死鎖恢復
以上的四個方法的約束一個比一個弱,死鎖預防的約束最強,而死鎖恢復的約束最差。
三、死鎖預防和死鎖避免
1. 死鎖預防——讓死鎖不會出現
思路:只要將之前所說的四個必要條件打破其中的一個,就不會出現死鎖。
針對死鎖的四個必要條件,打破死鎖進行一開始預防:
-
互斥:共享資源不是必須的,必須佔用非共享資源。即本來資源是互斥的,通過使資源不互斥。
-
佔用並等待:必須保證當一個進程請求的資源,它不持有其他任何資源。
-
將條件變大,拿資源就拿全部的資源纔去執行,否則不能資源去睡眠,這樣就不會存在死鎖。但是不同的
執行過程中,需要的資源不同,導致一直佔用資源但是沒有使用,所以會導致系統資源的利用率低。
-
-
不搶佔:直接將進程kill掉,也就將資源搶佔過來了,但是手段暴力,不合理。
-
循環等待:對所有資源類型進行排序,並要求每個進程按照資源的順序進行申請。
-
死鎖的出現會出現一個環,打破這個環可以實現死鎖的預防。如果對資源類型進行排序,要求進程按資源
順序進行申請,也就是資源只能往上進行申請,這樣就不會形成循環的圈。但是前提是要講資源排好序,
但是資源利用還是不合理的。
-
2. 死鎖避免
思路:當進程在申請資源的過程中,然後判斷這個申請合不合理,如果會存在死鎖的概率,就會拒絕這個請求。
需要系統具有一些額外的先驗信息提供:
- 最簡單和最有效的模式是要求每個進程聲明它可能需要的每個類型資源的最大數目。
- 資源的分配狀態是 通過限定提供與分配的資源數量和進程的最大需求。
- 死鎖避免算法動態檢查的資源分配狀態,以確保永遠不會有一個環形等待狀態。
當一個進程請求可用資源,系統必須立即分配是否能使系統處於安全狀態。
- 處於安全狀態:針對所有進程,存在安全序列(按照這個序列執行,先後順序執行,所以的進程都可以正常的等待所需要的資源,正常的結束)。
死鎖避免:確保系統永遠不會處於非安全狀態。
四、死鎖檢測和死鎖恢復
1. 死鎖檢測
死鎖檢測允許系統進入unsafe狀態,在某一個狀態判斷當前的系統是否出現死鎖,如果是,就啓動恢復機制;如果沒有,就繼續執行,將死鎖的檢測放在了系統運行中,更往後了。
死鎖檢測的大致思路
- 允許系統進入死鎖狀態
- 死鎖檢測算法
- 恢復機制
檢測原理:定期的檢測是否有環存在。
定期的執行對操作系統運行比較大,更多是起調試的作用。
2. 死鎖的恢復
- 終止所有的死鎖進程
- 在一個時間內終止一個進程直到死鎖消除
- 終止進程的順序應該是
- 進程的優先級
- 進程運行了多久以及需要多少時間才能完成
- 進程佔用的資源
- 進程完成需要的資源
- 多少進程需要被終止
- 進程是交互還是批處理
都存在某種程度上的強制性和不合理性。所以死鎖恢復是最後的手段。
五、進程間通信(IPC,Inter Processes Communication)
1. 問題:爲什麼要進行進程間通信?
- 進程之間可能要完成一個大的任務,這需要一定的數據的溝通和信息的傳遞,保存進程獨立性的通信,保證其可以有效的溝通。
2. IPC提供2個操作
- send message
- receive message
3. 通信的前提
- 在他們之間建立通信鏈路
- 通過send/receive交換消息
4. 通信鏈路實現
- 物理(例如共享內存,硬件總線)
- 邏輯(例如,邏輯屬性)
六、信號,管道,消息隊列和共享內存
1. 數據的緩衝
隊列的消息被附加到鏈路;可以是以下3種方式之一:
-
0容量- 0 messages
發送方必須等待接收方(rendezvous)
-
有限容量-n messages的有限長度
發送方必須等待,如果隊列滿
-
無限容量一無限長度
發送方不需要等待
2. 信號:軟件中斷通知事件處理
接收到信號時會發生什麼
-
Catch:指定信號處理函數被調用
-
Ignore: 依靠操作系統的默認操作
-
Mask: 閉塞信號因此不會傳送
可能是暫時的(當處理同樣類型的信號)
不足:不能傳輸要交換的任何數據
關注某一種信號,發生了某一種響應之後,可以編寫特定的處理函數。效率比較高。 處理完之後,會回到被打斷的函數重新的實現。
3. 管道:用來實現數據的交換。文件的操作。
-
思路:將一個文件的輸出,重定向到令一個文件的輸入,這樣就可以完成一系列的操作。(重定向符爲“>”)
-
實現:shell進程收到一條命令之後,會創建兩個進程,ls進程和more進程。同時將ls的輸出到一個管道中,
而不是屏幕上(內存中的一個buffer)。而對於more,不是從鍵盤接受信息,而是從管道中接受數據,這樣
就完成了輸入輸出的重定向功能。這樣就完成了分頁顯示目錄的功能。(存在阻塞現象)
-
特點:
- 管道是通過父進程幫子進程建立好的一個通道,如果沒有父子關係,這樣就不能正常工作了。
- 管道的數據是一種字節流。
- 有bufffer滿和buffer空的限制。
4. 消息隊列:按照FIFO來管理消息
特點:
- 數據是結構化的數據,而不是字節流,傳進去的是一個有意義的數據結構;
- 可以實現多個互不相關的進程完成數據交換 。
5. 共享內存
上面兩種都是間接通信。共享內存是直接通信的方式。(通過內核,讀寫內存,實現進程的數據的交換)
-
進程
- 每個進程都有私有地址空間
- 在每個地址空間內,明確地設置了共享內存段
-
優點:快速、方便地共享數據
不足:必須同步數據訪問