操作系統-死鎖

1. 死鎖的概念

1.1 哲學家就餐問題

問題描述:五個哲學家圍坐在圓桌邊,有5支筷子。他們做的事就是:思考-休息-吃飯

吃飯時使用兩支筷子:

  • 拿一雙筷子才能吃飯
  • 每次只能取一支筷子
  • 只取身邊的筷子
  • 吃完放下筷子

在這裏插入圖片描述
用線程實現哲學家的生活,如下僞代碼所示:

int signal[5] = [1, 1, 1, 1, 1]; //筷子i是否可用:0=不可用;1=可用
Philosopher (int i)
{
	while(TRUE){
		思考;
		休息;
		P(signal[i]); //取左邊的筷子;
		P(signal[(i+4)%5]); //取右邊的筷子;
		吃飯;
		V(signal[(i+4)%5]); //放下右邊的筷子;
		V(signal[i]); //放下左邊的筷子;
		放下右邊的筷子;
		放下左邊的筷子;
	}
}

假如5個哲學家在同一時刻吃飯,大家都拿起了左邊的筷子,但是右邊的筷子沒有,所有人都在等待右邊人放下手中的筷子。而右邊的人沒有吃完之前又不會放下筷子,所以所有的人都缺一支筷子永遠無法吃完飯,這時候就陷入了死鎖

1.2 死鎖定義

兩個或多個進程無限期地等待永遠不會發生的條件的一種系統狀態。其結果就是每個進程都永遠阻塞。

另一種定義:在兩個或多個進程中,每個進程都持有某種資源,但又繼續申請其他的進程已持有的資源,此時每個進程都擁有其運行所需的一部分資源,但是又都不夠,從而每個進程都無法向前推進,限於阻塞狀態。這種狀態稱爲死鎖。

2. 死鎖的起因

  • 系統資源有限:資源的數目不足,進程對資源競爭導致死鎖
  • 併發程序的推進順序不當:進程請求資源和釋放資源的順序不當,導致死鎖
  • 不正當的P-V操作也可能會帶來死鎖

2.1 死鎖的一些結論

  • 參與死鎖的進程至少是兩個
  • 參與死鎖的進程至少有兩個已經佔有資源
  • 參與死鎖的所有進程都在等待資源
  • 參與死鎖的進程是當前系統中所有進程的子集
  • 死鎖會浪費大量的系統資源,甚至導致系統崩潰

3. 死鎖的預防策略

3.1 死鎖的必要條件

條件 描述
互斥條件 進程互斥使用資源,資源具有獨佔性
不剝奪條件 進程在訪問完資源前不能被其他進程強行剝奪
部分分配條件 進程邊運行邊申請資源,臨時需要臨時分配
環路條件 多個進程構成環路:環中每個進程已佔用的資源前一進程所示,而自己所申請的資源又被環中後已進程佔用着

在這裏插入圖片描述

上面討論的哲學家吃飯問題,如果限定最多隻有4人同時吃飯,就可以避免死鎖。因爲此時環路條件被破壞了。

3.2 解決死鎖策略

通過設置某些限制條件,破壞死鎖的四個必要條件中的一個或多個來防止死鎖.

  • 破壞互斥條件(難)
  • 破壞不剝奪條件(代價大)
  • 破壞部分分配條件(預先靜態分配)
  • 破壞環路條件(有序資源分配)

3.2.1 預先靜態分配法

進程運行前將所需資源一次性全部分配給它。因此進程在運行的過程中不再提出資源請求,從而避免出現阻塞或死鎖。

特點:

  • 執行可能被延遲
  • 應用開銷大:運算前要估算資源請求
  • 資源利用率低:資源被佔用而不用

改進:

  • 資源分配的單位油由進程改爲程序步

3.2.2 有序資源分配法

系統中的每個資源有一個唯一序號,進程每次申請資源時只能申請序號更大的資源。如果進程已佔有資源的信號最大爲M,則下次申請只能申請大於M的資源,而不能申請序號小於M的資源。

實行過程:

  • 分配資源時檢查是否符合遞增規定
  • 若不符合,在拒絕申請,並撤銷該進程
  • 若符合,且資源可用則予以分配。若資源不可能則不分配,陷於阻塞

3.3 Windows和Linux採取的措施

鴕鳥策略

  • 不管死鎖,選擇相信開發人員。不採取任何措施。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章