第三章 處理機調度與死鎖
在多道程序系統中,一個作業從提交到執行, 通常都要經過多級調度,而系統運行的性能在很大程度上取決於調度,因此調度便成為操作系統設計的一個中心問題之一。
3.1、 處理機調度概述
3.1.1、 處理機調度的層次
1、高級調度--作業調度,長程調度
作業調度的主要功能是根據作業控制塊中的信息, 審查系統能否滿足用戶作業的資源需求,以及按照一定的算法,從外存的后備隊列中選取某些作業調入內 存,並為它們創建進程、分配必要的資源。然后再將新創建的進程插入就緒隊列,准備執行。因此,有時也把作業調度稱為接納調度(Admission Scheduling)。
2、 低級調度
低級調度的功能---進程調度,短程調度
(1)保存處理機的現場信息
(2)按某種算法選取進程
(3)把處理機分配給進程
3、中級調度---交換調度
1、目的:提高內存利用率和系統吞吐量。
2、方法:
(1)將暫時不能運行的進程調至外存上去等待, 此時進程狀態為:就緒駐外存狀態或掛起狀態。
(2)再次滿足運行條件時,由中級調度把外存上 的具備運行條件的進程,調入內存,掛在就緒隊列上等待進程調度
3.1.2、作業與作業調度
1 、作業
(1) 作業(Job)。作業是一個比程序更為廣泛的概念,它不僅包含了通常的程序和數據,而且還應配有一份作業說明書, 系統根據該說明書來對程序的運行進行控制。在批處理系統 中,是以作業為基本單位從外存調入內存的。
(2) 作業步(Job Step)。通常,在作業運行期間,每個作業都必須經過若干個相對獨立,又相互關聯的順序加工步 驟才能得到結果,我們把其中的每一個加工步驟稱為一個作業步,各作業步之間存在着相互聯系,往往是把上一個作業 步的輸出作為下一個作業步的輸入。
例如,一個典型的作業 可分成三個作業步:① “編譯”作業步,通過執行編譯程序 對源程序進行編譯,產生若干個目標程序段;② “連結裝配” 作業步,將“編譯”作業步所產生的若干個目標程序段裝配 成可執行的目標程序;③ “運行”作業步,將可執行的目標程序讀入內存並控制其運行。
(3)作業流。若干個作業進入系統后,被依次存放在外存 上,這便形成了輸入的作業流;在操作系統的控制下,逐個 作業進行處理,於是便形成了處理作業流。
2、作業控制塊JCB
為了管理和調度作業,在多道批處理系統中為每個作業設置了一個作業控制塊,如同進程控制塊是進程在系統中存 在的標志一樣,它是作業在系統中存在的標志,其中保存了 系統對作業進行管理和調度所需的全部信息。
在JCB中所包含 的內容因系統而異,通常應包含的內容有:作業標識、用戶 名稱、用戶帳戶、作業類型(CPU 繁忙型、I/O 繁忙型、批量 型、終端型)、作業狀態、調度信息(優先級、作業已運行時 間)、資源需求(預計運行時間、要求內存大小、要求I/O設備 的類型和數量等)、進入系統時間、開始處理時間、作業完成時間、作業退出時間、資源使用情況等。
每當作業進入系統時,系統便為每個作業建立一個JCB, 根據作業類型將它插入相應的后備隊列中。作業調度程序依 據一定的調度算法來調度它們,被調度到的作業將會裝入內 存。在作業運行期間,系統就按照JCB中的信息對作業進行 控制。當一個作業執行結束進入完成狀態時,系統負責回收分配給它的資源,撤消它的作業控制塊。
3、作業運行的三個階段和三個狀態
4、作業調度的任務
- 接納多少個作業
- 接納哪些作業
對用戶而言,總希望自己作業的周轉時間盡可能的少, 最好周轉時間就等於作業的執行時間。然而對系統來說,則希望作業的平均周轉時間盡可能少,有利於提高CPU 的利用率和系統的吞吐量。為此,每個系統在選擇作業調度算法時, 既應考慮用戶的要求,又能確保系統具有較高的效率。在每次執行作業調度時,都須做出以下兩個決定。
1) 決定接納多少個作業作業調度每次要接納多少個作業進入內存,取決於多道 程序度(Degree of Multiprogramming),即允許多少個作業同時 在內存中運行。當內存中同時運行的作業數目太多時,可能 會影響到系統的服務質量,比如,使周轉時間太長。但如果 在內存中同時運行作業的數量太少時,又會導致系統的資源 利用率和系統吞吐量太低,因此,多道程序度的確定應根據 系統的規模和運行速度等情況做適當的折中。
2)決定接納哪些作業 應將哪些作業從外存調入內存,這將取決於所采用的調度算法。最簡單的是先來先服務調度算法,這是指將最早進 入外存的作業最先調入內存;較常用的一種算法是短作業優先調度算法,是將外存上最短的作業最先調入內存;另一種 較常用的是基於作業優先級的調度算法,該算法是將外存上 優先級最高的作業優先調入內存;比較好的一種算法是“響 應比高者優先”的調度算法。我們將在后面對上述幾種算法 作較為詳細的介紹。
在批處理系統中,作業進入系統后,總是先駐留在外存的后備隊列上,因此需要有作業調度的過程,以便將它們分批地裝入內存。然而在分時系統中,為了做到及時響應,用 戶通過鍵盤輸入的命令或數據等都是被直接送入內存的,因 而無需再配置上述的作業調度機制,但也需要有某些限制性措施來限制進入系統的用戶數。即,如果系統尚未飽和,將接納所有授權用戶,否則,將拒絕接納。類似地,在實時系統中通常也不需要作業調度。
3.1.3、進程調度
1、低級調度的任務
(1)保存處理機的現場信息
(2)按某種算法選取進程
(3)把處理機分配給進程
2、進程調度的三個基本機制
(1)排隊器(進程隊列);
(2)分派器(分派程序)(調度程序)
(3)上下文切換機制(環境信息切換)
3、進程調度的方式
(1)非搶占方式(Non-preemptive Mode)
引發調度的事件:
① 正在執行的進程執行完畢;
② 發生某事件而不能再繼續執行;
③ 執行中的進程因提出I/O請求而暫停執行;
④ 執行了某種原語操作。
特點:實現簡單、系統開銷小,適用於大多數的批 處理系統環境,難以滿足緊急任務的要求。
(2) 搶占方式 (Preemptive Mode)
搶占的原則:
(1) 優先權原則
(2) 短作業(進程)優先原則
(3) 時間片原則
3.1.4、處理機調度算法的目標
1、處理機調度算法的共同目標
(1) 資源利用率
(2) 公平性
(3) 平衡性
(4) 策略強制執行
2、批處理系統的目標
(1)周轉時間:從作業提 交給系統開始,到作業完成這 段時間間隔。
3、分時系統的目標
1)響應時間快
2)均衡性
4、實時系統的目標
1)截止時間的保證
2)可預測性
3.2、調度算法
3.3.1、先來先服務和短作業(進程)優先調度算法
1、先來先服務調度算法(FCFS)
2、短作業(進程)優先調度算法(SJF / SPF)
SJF/SPF算法的缺點:
(1) 對長作業(進程)不利。調度程序總是優先調 度那些(即使是后進來的)短作業(進程),可能使 長作業(進程)長期不被調度。
(2) 未考慮作業(進程)的緊迫程度。不能保證緊 迫性作業(進程)被及時處理。
(3) 作業(進程)的長短沒有客觀標准。可能有失 公平,損害算法初衷。
3.2.3、優先級調度算法
1、優先權調度算法的類型
(1)非搶占式優先權算法
主要用於批處理系統中;
(2) 搶占式優先權調度算法
能更好地滿足緊迫作業的要求,常用於要求比較嚴格的實時系統中, 以及對性能要求較高的批處理系統 和分時系統中。
2、優先權的類型
(1)靜態優先權
優先權是在創建進程時確定,在進程的整個運行期間 保持不變。
優先權的確定依據:進程類型,進程對資源的需求, 用戶要求。
(2) 動態優先權
動態優先權是指,在創建進程時所賦予的優先權,是 可以隨進程的推進或隨其等待時間的增加而改變的,以便 獲得更好的調度性能。
3、高響應比優先調度算法
(2)高響應比優先調度算法優點:
*等待時間相同,要求服務的時間愈短,優先權愈高,算法有利於短作業。
*要求服務的時間相同,等待時間愈長,其優先權愈高,實現了先來先服務。
*長作業優先級隨等待時間的增加而提高,最終也可獲得處理機,確保了長作業的執行。
3.2.4、基於時間片的輪轉調度算法
1、 時間片輪轉法基本原理
(1)把CPU按時間片分配給進程,進程按時間片 大小輪流執行。
(2)保證就緒隊列中的所有進程,在一給定的時 間內,均能獲得一時間片的處理機執行時間。(響應 時間)
(3)時間片的大小從幾ms到幾百ms.
2、進程切換時機
(1)若一個時間片尚未用完,正在運行的進程已經完成,則調度激活程序,將已經完成的進程從就緒隊列中刪除,再調度就緒隊列中隊首進程運行,並啟動一個新的時間片。
(2)當一個時間片用完,計時器中斷處理程序被激活。此時,若進程尚未運行完成,調度程序把它送到就緒隊列末尾。
3、 時間片大小確定

3.2.5、多級隊列調度算法
在進程容易分成不同組的情況下,可以有另一類調度算法。例如, 進程通常分為前台進程(或交互進程)和后台進程(或批處理進程)。 這兩種類型的進程具有不同的響應時間要求,進而也有不同調度需要。 另外,與后台進程相比,前台進程可能要有更高的優先級(外部定 義)。多級隊列調度算法將就緒隊列分成多個單獨隊列根據進程屬性, 如內存大小、進程優先級、進程類型等,一個進程永久分到一個隊列, 每個隊列有自己的調度算法。
3.2.6、多級反饋隊列調度算法

3.3.7、基於公平原則的調度算法
1、 保證調度算法
2、公平分享調度算法
3.3、實 時 調 度
不做要求
3.5、死鎖概述
3.5.1、資源問題
- 可重用性資源和消耗性資源
1)可重用性資源
2)可消耗性資源
- 可搶占性資源和不可搶占性資源
1)可搶占性資源
2)不可搶占性資源
3.5.2、計算機系統中的死鎖
死鎖: 指多個進程因競爭資源而造成的一種僵局,若無外力作用,這些進程都將永遠不能再向前推進。
產生死鎖的原因:
- 競爭資源
- 進程間推進順序非法
1、競爭不可搶占性資源引起進程死鎖
2 、競爭可消耗性資源
3、進程推進順序不當引起的死鎖
當進程P1、P2共享資源A、B時,若推進順序合法則不會產生死鎖, 否則會產生死鎖。
合法的推進路線:①②③ 不合法的推進線路:④

3.5.3、死鎖的定義、必要條件和處理方法
1、死鎖的定義
如果系統中的每一個進程都在等待僅由該組進 程中的其他進程才能引發的事件,那么該組進程就是死鎖的。
2、 產生死鎖的必要條件
(1) 互斥條件
(2) 請求和保持條件
(3) 不剝奪條件
(4) 環路等待條件
3、處理死鎖的基本方法
(1) 預防死鎖
(2) 避免死鎖
(3) 檢測死鎖
(4) 解除死鎖
3.5.4、資源分配圖

3.6、預防死鎖的方法
3.6.1、破壞“請求和保持”條件
1、第一種協議
系統要求所有進程要一次性地申請在整個運行過程所需要的全部資源。
摒棄請求條件:進程在整個運行期間,不再提 出資源要求。
摒棄保持條件:等待期間進程不占有任何資源。
優點:簡單、易於實現、且安全。
缺點: (1)資源嚴重浪費 (2)進程延遲運行
2、第二種協議
思想:允許一個進程只獲得運行初期所需的資源后,便開始運行。進程運行過程中再逐步釋放已分配給自己、且已用完的全部資源,然后再請求新的所需資源。
3.6.2、摒棄“不可搶占”條件
思想:允許進程還未執行完成時釋放已經占有的資源。
方法:
- 如果得不到滿足,則先釋放所占有的所有資源。
- 高優先級的進程優先請求相同資源,並能剝奪低優先級進程的資源。
局限: 實現復雜,代價較大,為了恢復現場需要耗費很多時間和空間。只適合類似CPU、存儲器這樣的資源。
3.6.3、破壞“循環等待”條件
方法:
給資源編號,進程必須按序申請資源。
局限:
- 資源編號困難
- 申請資源的順序很難和資源編號順序相一致
- 限制了用戶對資源調用的靈活性
3.7、死鎖避免
3.7.1、系統安全狀態
所謂安全狀態,是指系統能按某種進程順序(P1, P2, …, Pn)(稱ǿP1, P2, …, PnȀ序列為安全序列),來為每個進程Pi 分配其所需資源,直至滿足每個進程對資源的最大需求,使每個進程都可順利地完成。
如果系統無法找到這樣一個安全序列,則稱系統處於不安全狀態。
避免死鎖的關鍵就是:讓系統在動態分配資源的過程中,不要進入不安全狀態。
2、安全狀態之例
3、由安全狀態向不安全狀態的轉換
如果不按照安全序列分配資源,則系統可能會由安全狀態進入不安全狀態,進而可能造成死鎖。
3.7.2、利用銀行家算法避免死鎖
1965年由Dijkstra為T.H.E系統設計
基本思想:借用了銀行借貸系統的分配策略。
基本規則:
(1)第一次申請需要聲明最大資金需求量
(2)滿足最大需求后要及時歸還資金
(3)客戶申請的貸款數量不超過它自己擁有的最大值時,銀行要盡量滿足客戶需求
客戶---->資金
銀行---->進程
資源---->操作系統
1、 銀行家算法中的數據結構
(1) 可利用資源向量Available,表示系統中可利用的資 源的數目;如Available[j]=K,表示系統中Rj 類資源有K 個。
(2) 最大需求矩陣Max,表示n個進程中的各進程對m類 資源的最大需求,如Max[i, j]=K,表示進程i需要Rj 類資 源的最大數目為K個。
(3) 分配矩陣Allocation,表示各進程當前已分得各類資源 的數目;如Allocation[i, j]=K,表示進程i當前已分得K 個Rj 類資源。
(4) 需求矩陣Need,表示各進程尚需的各類資源的數目; 如Need[i, j]=K,表示進程i還需要K個Rj類資源,方能完成其任務。
Need[i,j]=Max[i,j]-Allocation[i,j]
2、銀行家算法
(1) 如果Requesti [j]≤Need[i,j],便轉向步驟2;否則 認為出錯,因為它所需要的資源數已超過它所宣布的最大值。
(2) 如果Requesti [j]≤Available[j],便轉向步驟3; 否則, 表示尚無足夠資源,Pi 須等待。
(3) 系統試探着把資源分配給進程Pi ,並修改下面數據結 構中的數值: Available[j]: =Available[j]- Requesti [j]; Allocation[i,j]: =Allocation[i,j]+ Requesti [j]; Need[i,j]: =Need[i,j]- Requesti [j];
(4) 系統執行安全性算法,檢查此次資源分配后,系統 是否處於安全狀態。若安全,才正式將資源分配給進程Pi ; 否則,恢復原來的資源分配狀態,讓進程Pi 等待。

3、 安全性算法
(1)設置兩個向量:
① 工作向量Work: 表示系統可提供給進程繼續運行 的各 類 資源 數 目 , 在 執行安全算法開始時 , Work=Available;
② Finish: 表示系統是否有足夠的資源分配給進程, 開始時先做Finish[i]:=false; 當有足夠資源分配給進程時, 再令Finish[i]=true.
(2)從進程集合中找到一個能滿足下述條件的進程:
① Finish[i]=false 且
② Need[i,j]≤Work[j]; 若找到, 執行步驟(3), 否則,執行步驟(4)。
(3)進程Pi 獲得資源后,能順利完成,並釋放全部資 源,則修改向量: Work[j]:= Work[i]+ Allocation[i,j]; Finish[i]:= true; go to step 2;
(4) 如果所有進程的Finish[i]=true都滿足, 則表示系統處於安全狀態;否則,系統處於不安全狀態。
設置兩個向量: work、 Finish
從進程集合中找到一個能滿足下述條件的進程: Finish[i] = false & Needi <= work
執行:
Work := Work + Allocation;
Finish[i] := true;
循環,如果所有進程的Finish[i] = true則安全。
5、 銀行家算法的優缺點
優點:
- 提高了資源利用程度
- 系統總是處於安全狀態
缺點:
- 被分配的每類資源的數量是固定不變的;
- 用戶數保持固定不變;
- 要求用戶事先說明其最大資源要求。
3.8、死鎖的檢測與解除
3.8.1、死鎖的檢測
要求:
- 資源請求與分配信息
- 檢測算法和解除算法
1、資源分配圖(Resource Allocation Graph)
資源分配圖化簡:
2、死鎖定理
當且僅當系統某狀態S所對 應的資源分配圖是不可完全化簡的,則S是死鎖狀態,而相應進程被死鎖。
如果資源分配圖中沒有環路,則系統中沒有死鎖,如果圖中存在環路則系統中可能存在死鎖
如果每個資源類中只包含一個資源實例,則環路是死鎖存在的充分必要條件。
有環有死鎖

有環無死鎖

3、 死鎖檢測中的數據結構
(1) 可利用資源向量Available,它表示了m類資源中每一 類資源的可用數目。
(2) 把不占用資源的進程(向量Allocation∶=0)記入L表中, 即Li ∪L。
(3) 從進程集合中找到一個Requesti ≤Work的進程,做如下處理:
① 將其資源分配圖簡化,釋放出資源,增加工作向 量Work∶=Work+Allocationi 。
② 將它記入L表中。
(4) 若不能把所有進程都記入L表中, 便表明系統狀態S 的資源分配圖是不可完全簡化的。 因此,該系統狀態將發生死鎖。
3.8.2、死鎖的解除
重新啟動:這是一種常用但比較粗暴的方法,雖然實現簡單,但會使之前的工作全部白費,造成很大的損失和浪費。
撤消進程:死鎖發生時,系統撤消造成死鎖的進程, 解除死鎖。 一次性撤消所有的死鎖進程。損失較大。 逐個撤消,分別收回資源。
具體做法:系統 可以先撤消那些優先級低的、已占有資源少 或已運行時間短的、還需運行時間較長的進 程,盡量減少系統的損失。
剝奪資源:死鎖時,系統保留死鎖進程,只剝奪死 鎖進程占有的資源,直到解除死鎖。選擇被剝奪資源進程的方法和選擇被撤消進程相同。
進程回退:死鎖時,系統可以根據保留的歷史信息, 讓死鎖的進程從當前狀態向后退回到某種狀態,直到死鎖解除。
實現方法:可以通過結合檢查點或回退機制實現。