一、死結
(1) 死結是指多個進程之間相互等待對方的資源,而在得到對方資源之前又不釋放自己的資源,這樣,造成迴圈等待的一種現象。如果所有進程都在等待一個不可能發生的事,則進程就死結了。
(2)死結產生的必要條件:
互斥條件
進程對資源進行排它性使用,即在一段時間內某資源僅為一個進程所佔用。
請求和保持條件
當進程因請求資源而阻塞時,對已獲得的資源保持不放。
不可剝奪條件
進程已獲得的資源在未使用完之前,不能被剝奪,只能在使用完時由自己釋放。
環路等待條件
各個進程組成封閉的環形鏈,每個進程都等待下一個進程所佔用的資源
(3)防止死結的辦法
資源一次性分配:(破壞請求和保持條件)
可剝奪資源:(破壞不可剝奪條件)
資源有序分配法:(破壞迴圈等待條件)
(4)死結避免
預防死結的幾種策略,會嚴重地損害系統效能。因此在避免死結時,要施加較弱的限制,從而獲得較滿意的系統效能。
由於在避免死結的策略中,允許進程動態地申請資源。因而,系統在進行資源分派之前預先計算資源分派的安全性。若此次分配不會導致系統進入不安全狀態,則將資源分派給進程;否則,進程等待。其中最具有代表性的避免死結演算法是銀行家演算法。
(5)銀行家演算法
為保證資金的安全,銀行家規定:
* 當一個顧客對資金的最大需求量不超過銀行家現有的資金時就可接納該顧客;
* 顧客可以分期貸款,但貸款的總數不能超過最大需求量
* 當銀行家現有的資金不能滿足顧客尚需的貸款數額時,對顧客的貸款可延遲支付,但總能使顧客在有限的時間裡得到貸款
* 當顧客得到所需的全部資金後,一定能在有限的時間裡歸還所有的資金.
(6)哲學家就餐問題
五個哲學家圍在一個圓桌就餐,每個人都必須拿起兩根筷子才能用餐,當每個人都先拿起左筷子,等待右筷子的時候就會造成死結。
哲學家就餐問題解法
服務生解法
最多4個哲學家
僅當一個哲學家兩邊筷子都可用時才允許他拿筷子
給所有哲學家編號,奇數號的哲學家必須首先拿左邊的筷子,偶數號的哲學家則反之
二、訊號量與PV原語
(1)訊號量
訊號量和P、V原語由Dijkstra(迪傑斯特拉)提出
struct semaphore
{
int value;
pointer_PCB queue;
};
訊號量
互斥:P、V在同一個進程中
同步:P、V在不同進程中
訊號量值含義
S>0:S表示可用資源的個數
S=0:表示無可用資源,無等待進程
S<0:|S|表示等待隊列中進程個數
(2)P原語虛擬碼
P(s)
{
s.value = s.value--;
if (s.value < 0)
{
該進程狀態置為等待狀狀態
將該進程的PCB指標插入相應的等待隊列s.queue末尾
}
}
注意,PV 操作都是原子性操作,要麼全部執行要麼全部不執行,在阻塞後返回也算是完成一個流程,但如果設定了IPC_NOWAIT選項,當資源暫且不可用時直接返回錯誤,此時對訊號量的操作都沒有執行。
(3)V原語虛擬碼
V(s)
{
s.value = s.value++;
if (s.value < =0)
{
喚醒相應等待隊列s.queue中等待的一個進程
改變其狀態為就緒態
並將其插入就緒隊列
}
}
(4)用PV原語解決司機與售票員問題
(5)用PV原語解決民航售票問題
每個用戶端都在執行PV這樣的操作流程
(6)用PV原語解決汽車租賃問題
有一汽車租賃公司有兩部敞篷車可以出租,假定同時來了四個顧客都要租敞篷車,那麼肯定會有兩個人租不到。
每個顧客都在執行PV這樣的操作流程。
參考:
《TCP/IP詳解 卷一》
《UNP》