1. 程式人生 > >第三章 處理機排程與死鎖(二)

第三章 處理機排程與死鎖(二)

3.6 預防死鎖

1. 破壞“請求和保持”條件

所有程序在開始執行之前,必須一次性地申請其在整個執行過程中所需的全部資源。

  1. 優點:簡單、易行且安全
  2. 缺點:①資源被嚴重浪費 ②使程序經常會發生飢餓現象

2. 破壞“不可搶佔”條件

允許程序先執行,提出新的資源請求而不能得到滿足時,必須釋放已經保持的所有資源,待以後需要時重新申請。
實現比較複雜,且需付出很大代價,可能會造成程序前一階段工作的失效,反覆申請和釋放資源。

3. 破壞“迴圈等待”條件

對系統所有資源型別進行線性排序,並賦予不同的序號,每個程序必須按序號遞增的順序請求資源。在採用這種策略後所形成的資源分配圖中,不可能再出現環路。
與前兩種策略比較,其資源利用率和系統吞吐量都有較明顯的改善,但也存在以下問題:
3. 為系統中各類資源所規定的序號,限制了新型別裝置的增加;
4. 作業使用各類資源的順序與系統規定的順序不同;
5. 會限制使用者程式設計自由。

3.7 避免死鎖

1. 安全狀態:是指系統能按某種程序推進順序(P1,P2,…,Pn)為每個程序Pi分配其所需資源,直至滿足每個程序對資源的最大需求,使每個程序都可順利地完成。

(P1,P2,…,Pn)為安全序列。
6. 最終釋放的總資源為所有資源總和,可檢查是否計算出錯。
7. 並非所有不安全狀態都必然會轉為死鎖狀態,不安全狀態一旦出錯才有可能轉為死鎖狀態。
8. 只要系統處於安全狀態,系統便不會進入死鎖狀態。

2.利用銀行家演算法避免死鎖

  • 資料結構:
    ①可利用資源向量Available
    ②最大需求矩陣Max
    ③分配矩陣Allocation
    ④需求矩陣Need
  • 銀行家演算法:
    設Request是程序Pi的請求向量,如果Request[j] = K,表示程序Pi需要K個Rj型別的資源。當Pi發出資源請求後,系統按下述步驟進行檢查:
    ①如果Request[j]≤Need[i , j],便轉向步驟②;否則認為出錯,因為它所需要的資源數已超過它所宣佈的最大值。
    ②如果Request[j]≤Available[j],便轉向步驟③;否則,表示尚無足夠的資源,Pi須等待。
    ③系統試探著把資源分配給程序Pi,並修改下面資料結構中的數值:
    Available[j] -= Request[j];
    Allocation[i , j] += Request[j];
    Need[i , j] -= Request[j];
    ④系統執行安全性演算法,檢查此次資源分配後系統是否處於安全狀態。若安全,才正式將資源分配給程序Pi,以完成本次分配;否則,將本次的試探分配作廢,恢復原來的資源分配狀態,讓程序Pi等待。
  • 安全性演算法
    ①設定兩個向量:①工作向量Work,它表示系統可提供給程序繼續執行所需的各類資源數目,它含有m個元素,在執行安全演算法開始時,Work = Available;②Finish:它表示系統是否有足夠的資源分配給程序,使之執行完成。開始時先做Finish[i] = false;當有足夠資源分配給程序時,再令Finish = true。
    ②從程序集合中找到一個能滿足下述條件的程序:
    Finish[i] = false;
    Need[i , j] ≤ Work[j];
    若找到,執行步驟③,否則,執行步驟④。
    ③當程序Pi獲得資源後,可順利執行,直至完成,並釋放出分配給它的資源,故應執行:
    Work[j] += Allocation[i , j];
    Finish[i] = true;
    go to step 2;
    ④如果所有程序的Finish[i] = true都滿足,則表示系統處於安全狀態;否則,系統處於不安全狀態。
  • 銀行家演算法示例
    假定系統中有五個程序{P0,P1,P2,P3,P4}和三類資源{A,B,C},各種資源的數量分別為10、5、7,在T0時刻的資源分配情況如圖所示。
    在這裡插入圖片描述
    計算舉例:當前T0時刻是否安全?
    利用安全性演算法在下表找一個安全序列{P1,P3,P4,P2,P0},故是安全的。(最後檢查應是資源釋放完後又回到10、5、7 )
    在這裡插入圖片描述

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
(1)T0時刻的初始狀態是安全的;
(2)下面出現P1請求資源的操作,具體請求向量為Request1(1,0,2),利用銀行家演算法進行檢查該操作是否是安全可行的:
1)兩個基本判斷
Request1(1,0,2)<=Need1(1,2,2)
Request1(1,0,2)<=Available1(3,3,2)
2)先假設為P1分配資源,並修改Available,Allocation1和Need1向量。
3) Request1(1,0,2)後新的資源狀態表下再判斷新資源狀態是否是安全的。
找到一個安全序列{P1,P3,P4,P0,P2},因此係統是安全的,該請求是安全的,可將假設真正實施,將P1所申請的資源分配給它。
在這裡插入圖片描述
問:P4發出請求向量Request(3,3,0),可否分配資源?
1)Request(3,3,0)≤Need(4,3,1);
2)Request(3,3,0)≥Available(2,3,0),P4等待
問:P0發出請求向量Request0(0,2,0),可否分配資源?
1)Request0(0,2,0)<=Need0(7,4,3);
2)Request0(0,2,0)<=Available(2,3,0);
3)系統暫時先假定可為P0分配資源,並修改有關資料,見下表:
在這裡插入圖片描述
Available(2,1,0)不能滿足任何finish=false程序的需求,如果分配會使系統進入不安全狀態,所以不能分配資源。
如果把P0發出的請求向量改為Request0(0,1,0),如下圖:
在這裡插入圖片描述

3.8 死鎖的檢測與解除

1.檢測時機

  • 當程序等待時檢測死鎖
  • 定時檢測
  • 系統資源利用率下降時檢測死鎖

2.資源分配圖的簡化方法:

  • 在資源分配圖中,找出一個既不阻塞又非獨立的程序結點Pi。在順利的情況下,Pi執行完畢,再釋放其所佔有的全部資源。
  • 由於釋放了資源,這樣能使其他被阻塞的程序獲得資源繼續執行,消去了Pi的邊。
  • 在進行一系列的簡化後,若能消去圖中所有的邊,使所有的程序結點都成為孤立的結點,則稱該圖是可完全簡化的。

3.死鎖檢測演算法

  • 每個程序和資源指定唯一編號
  • 設定一張資源分配表
  • 設定一張程序等待表
  • 反覆檢測這兩張表,列出所有等待與分配的關係,若出現迴圈等待,則出現了死鎖。

4.·一個有N個程序的單處理機系統,在死鎖時,可能出現N個程序都阻塞的情況,即在搶奪除CPU以外的資源時可能出現。