一、CPU調度概述
1.長程調度
- 又稱作業調度或高級調度
- 處於新建狀態的進程一般首先被放到外存的進程池中,當內存進程的數量沒有達到最多進程數時,操作系統的調度程序才從新建狀態選擇一個進入內存並轉換為就緒狀態
- “新建”狀態轉換到“就緒”狀態
- 由調度程序選擇
- 控制多道程序的“道/度”
2.短程調度
- 又稱為CPU調度或低級調度
- 在就緒隊列中可能存在不止一個進程,當CPU空閑時,操作系統就需要從就緒隊列中挑選一個進程讓它運行
3.長程調度與短程調度的比較
4.中程調度
- 又稱為交換
- 從本質上講,中程調度不屬於進程管理的內容,而應該屬於內存管理
- 一個進程在內存和外存間的換進換出,最大的目的是節省內存
- 當一個進程在內存中長期不運行時,會造成內存浪費,為此,操作系統把這些進程從內存換道外存,從而騰出內存空間供運行進程使用
- 當一個在外存的進程接下來需要運行時,操作系統則執行還如操作,把這個進程從外存換入內存
5.進程調度隊列
- 為了方便進行CPU調度,操作系統需要對不同狀態的進程進行組織和管理。為此操作系統為某些特定的狀態設立了一個或多個進程隊列,用於管理這些進程
- 作業隊列:在系統中的所有進程的集合
- 就緒隊列:在主存中的,就緒並等待執行的所有進程的集合,不必是先進先出隊列,隊列中的記錄通常是進程控制塊(PCB)
- 設備隊列:等待某一I/O設備的進程隊列
- 進程的執行過程實際上就是進程在各種隊列之間的遷移
6.CPU調度過程
- 調度程序
- 根據某種策略選擇內存中的一個就緒進程
- 一個CPU同時只能運行一個進程
- 做選擇
- 分派程序
- 負責把CPU的控制權轉交CPU調度程序
- 切換上下文
- 切換到用戶態
- 跳轉到用戶程序的適當位置並重新運行之
- 分派延遲:分派程序終止一個進程的運行並啟動另一個進程運行所花的時間
7.調度方式
- 非搶占式調度
- 一旦把CPU分配給某個進程后,系統不可以搶占已分配的CPU並分配給其他進程
- 只有進程自願釋放CPU,才可以把CPU分配給其他進程
- 優點:容易實現,調度開銷小,適合批處理系統
- 缺點:響應時間長,不合適交互系統
- 搶占式調度
- 調度程序可以根據某種原則暫停某個正在執行的進程,將已分配給它的CPU重新分配給另一個進程
- 當多個進程共享數據時,搶占調度可能導致競爭情況
- 搶占也影響操作系統的內核設計
- 可防止單一進程長時間獨占CPU
- 系統開銷大
- 受中斷影響的代碼應加以保護,從而避免同時使用,為了這些代碼段不被多個進程同時訪問,在進入時禁止中斷而退出時啟用中斷
- 搶占式與非搶占式的區分
- 運行進程是否是自願放棄CPU
- 運行進程是否是自願放棄CPU
8.CPU調度時機
- CPU調度可能發生在當一個進程
- 從運行轉到等待(非搶占式)
- 從運行轉到就緒(搶占式)
- 從等待轉到就緒(搶占式)
- 終止運行(非搶占式)
二、調度准則
- CPU利用率:固定時間內CPU運行時間的比例
- 吞吐量:單位時間內運行完的進程數
- 周轉時間:進程從提交到運行結束的全部時間
- 等待時間:進程等待調度(不在運行)的時間片總和
- 響應時間:從進程提出請求到首次被響應(而不是輸出結果)的時間段(在分時系統環境下),也就是第一段的等待時間
- 周轉時間=等待時間+運行時間
- 帶權周轉時間:周轉時間/運行時間
三、調度算法
1.先來先服務調度算法(FCFS)
- 調度策略:按照進程請求CPU的先后順序來使用CPU
- 調度依據:進入就緒隊列的時間
- 調度方法:先進入就緒隊列的進程被優先選中運行
- 使用FIFO隊列實現
- 特點:
- 實現簡單,可使用FIFO隊列實現
- 非搶占式調度
- 公平,每個進程都有被調度的機會
- 適用於長程調度,后台批處理系統的短程調度
- 對長CPU脈沖的進程有利,對短CPU脈沖的進程不利
- 護航效果:當一個長進程后面的多個短進程,讓長進程先執行,會讓后面的短進程等待較長時間,從而導致CPU和設備利用率降低
- 例:
2.短作業優先調度算法(SJF)
- 調度策略:關聯到每個進程下次運行的CPU脈沖長度,調度最短的進程
- 調度依據:每個進程下次運行的CPU脈沖長度
- 調度方法:調度最短的進程運行
- 兩種模式:
- 非搶占式調度:一旦進程擁有CPU,它可在該CPU脈沖結束后讓出CPU
- 搶占式調度:有比當前進程剩余時間更短的進程到達時,新來的進程搶占當前運行進程的CPU,也稱為最短剩余時間優先調度
- SJF最優:對一組的進程而言,它給出了最短的平均等待時間
- SJF算法困難:如何知道下一個CPU區間的長度
- SJF通常用於長程調度
- 指數估算法:通過先前的CPU區間長度及其指數平均進行預測
- 飢餓:長進程可能長時間等待,知道進程會運行但不知道什么時候運行
- 死鎖:進程長時間等待,不會運行
- 例:
3.優先級調度算法
- 目前主流的操作系統調度算法
- 調度依據:優先級
- 就緒隊列中的排列方式:優先級高的在前,優先級低的在后
- 調度方法:調度優先級最高進程運行
- 優先數:表示優先級的整數
- 可以參考不同的因素來設置(時間極限,內存要求,進程的重要性)
- 優先數可用某一范圍的整數來表示
- 靜態優先級:
- 進程創建時確定,在運行期間不變
- 簡單易行,系統開銷小
- 不夠精確,可能會出現飢餓問題
- 動態優先級:
- 進程創建時的優先級隨進程推進或等待時間增加而改變
- 調度模式:
- 搶占式調度
- 非搶占式調度
- 特點:
- 實現簡單,考慮了進程的緊迫程度
- 策略靈活,可模擬其他算法
- 存在問題:飢餓(低優先級的進程可能永遠得不到運行)
- 解決問題:視進程等待時間的延長提高其優先級
- 例:
4.時間片輪轉(RR)
- 為分時系統設計
- 算法原理:把一段時間分割成若干個小碎片,每個需要運行的進程獲得一個碎片運行,即在這段時間內,每個進程都得到運行
- 時間片:較小單位的CPU時間,通常為10-100毫秒
- RR算法的性能很大程度上取決於時間片的大小
- 時間片大->FCFS
- 時間片小->系統開銷大
- 一般准則:時間片/10>進程上下文切換時間
- 周轉時間也依賴時間片的大小
- 調度依據:進入就緒隊列的時間
- 調度方法:每個進程運行時間長度為一個時間片,時間片用完后,該進程被搶占並插入就緒隊列末尾
- 假定就緒隊列中有n個進程、時間片q
- 則每個進程每次得到不超過q單位的成塊CPU時間
- 沒有一個進程的等待時間會超過(n-1)q
- 在不超過nq時間內,n個進程都運行一次
- 例:
5.多級隊列調度(MLQ)
- 以上算法存在局限性,不能適應各種不同類型的進程
- SJF算法有利於短進程,而不利於長進程
- RR算法系統開銷大
- 優先級算法存在飢餓問題等
- 所有進程采用同一策略,不合理
- 不同類型的進程需要不同策略
- 交互進程需要較短的響應時間
- 批處理進程需要較短的等待時間
- 通常,交互進程較批處理進程的優先級高
- 多級隊列調度
- 允許系統中存在多個就緒隊列,每個就緒隊列有自己的調度算法
- 根據進程屬性,如內存大小、進程優先級、進程類型等,一個進程永遠分到一個隊列,每個隊列有自己的調度算法
- 隊列之間應有調度
- 通常采用固定優先級搶占調度,可能產生飢餓
- 另一種方法是在隊列之間划分時間片,每個隊列都有一定比例的CPU時間,可用於調度隊列內的進程
- 關鍵:
- 需要確定就緒隊列的數量
- 需要確定新進程進入那個隊列
- 需要確定每一個隊列的調度算法
- 例:
- 就緒隊列:
- 前台(交互式)
- 后台(批處理)
- 每個隊列有自己的調度算法
- 前台:RR
- 后台:FCFS
- 隊列間的調度方法
- 固定優先級調度,即前台運行完后再運行后台。有可能產生飢餓
- 給定時間片調度,即每個隊列得到一定的CPU時間,進程在給定時間內執行;如,80%的時間執行前台的RR調度,20%的時間 執行后台的FCFS調度
- 就緒隊列:
6.多級反饋隊列調度(MLFQ)
- 多級反饋隊列調度算法的核心是進程在運行過程中,能在不同隊列間移動
- 進程能在不同的隊列間移動:可實現老化
- 一種用於避免資源調度系統中的飢餓的技術
- 多級反饋隊列調度程序由以下參數定義:
- 隊列數
- 每一隊列的調度算法
- 決定需要服務的進程將進入哪個隊列的方法
- 決定進程升級的方法(低級隊列到高級隊列)
- 決定進程降級的方法(高級隊列到低級隊列)
- 優點:
- 比MLQ算法具有更好的靈活性
- MLFQ很好地解決了CPU調度問題
- Unix,Solaris,Windows的調度算法一定程度上都是MLFQ的變種
- 例:
四、線程調度
1.概念
- 在支持線程的操作系統上,內核級線程(而不是進程)才是操作系統所調度的
- 用戶級線程是由線程庫來管理的,而內核並不知道它們
- 用戶級線程為了運行在CPU上,最終映射到相關的內核級線程,但是這種映射可能不是直接的,可能采用輕量級進程
2.競爭范圍
- 進程競爭范圍(PCS):對於實現多對一和多對多模型的系統線程庫會調度用戶級線程,以便在可用輕量級進程(LWP)上運行,因為競爭CPU是發生在同一進程的線程之間
- PCS采用優先級調度,即調度程序選擇運行具有最高優先級的、可運行的線程。
- 用戶級線程的優先級是由程序員設置的,並不是由線程庫調整的
- 允許一個更高優先級的線程來搶占當前運行的線程
- 系統競爭范圍(SCS):決定哪個內核級線程調度到一個處理器上,采用SCS調度來競爭CPU,發生在系統內的所有線程之間
五、多處理調度
- 適用多核處理器的CPU調度
- 多個CPU可用時,CPU調度將更為復雜
1.多處理調度的方法
- 非對稱多處理器(ASMP):僅一個處理器能處理系統數據結構,減輕了對數據的共享需求。由這個主處理器負責調度,處理所有調度決定、I/O處理以及其他系統活動,其他處理器只執行用戶代碼
- 對稱多處理器(SMP):每個處理器決定自己的調度方案,主流方案
- 所有進程可能處於一個共同的就緒隊列中,或每個處理器都有它自己的私有就緒隊列
- 不管如何,調度這樣進行:每個處理器的調度程序都檢查共同就緒隊列,以便選擇執行一個進程
- 調度方法:和單處理器相似
2.處理器親和性
- 由於緩存的無效或重新填充的代價高,大多數SMP系統試圖避免將進程從一個處理器移到另一個處理器,而是試圖讓一個進程運行在同一個處理器上
- 進程要在某個給定的CPU上盡量長時間地運行而不被遷移到其他處理器的傾向性
- 高速緩存中的內容
- 軟親和性:當一個操作系統試圖保持進程運行在同一個處理器上時(但不會保證它會這么做),進程通常不會在處理器之間頻繁遷移
- 硬親和性:進程不會在處理器之間遷移,有的系統提供系統調用,從而允許某個進程運行在某個處理器子集上
- 系統的內存架構可以影響處理器的親和性
3.負載平衡
- 將任務平均分配給SMP系統的各個處理器
- 針對私有就緒隊列,而對公共隊列系統,負載平衡通常沒有必要,因為一旦處理器空閑,它立刻從公共隊列中取走一個可執行進程
- 和處理器親和性矛盾
- 保持一個進程運行在同一個處理器上的好處是進程可以利用它在該處理器緩存內的數據。無論是從一個處理器向另一個處理器推或拉進程,都會失去這個好處
- 方法:
- 推遷移:
- 對於推遷移,一個特定的任務周期性地檢查每個處理器的負載,如果發現不平衡,那么通過將進程從超載處理器推到空閑或不太忙的處理器,從而平均分配負載
- 拉遷移:
- 當空閑處理器從一個忙的處理器上拉一個等待任務時,發生拉遷移
- 推遷移和拉遷移不必相互排斥,事實上,在負載平衡系統中它們常被並行實現
- 推遷移:
4.單隊列調度方法
- 系統有一個就緒隊列。當任意一個CPU空閑時,就從就緒隊列中選擇一個進程到該CPU上運行
- 優點:
- 容易從單核調度算法推廣到多核/多處理器
- 實現簡單,負載均衡
- 缺點:
- 不具有親和性,一個進程可能在不同時候被調度到不同的CPU
- 多核同時訪問一個隊列,會有加鎖問題,從而嚴重影響調度的性能
5.多隊列調度方法
- 系統有多個就緒隊列,一般每個CPU一個隊列。每個就緒隊列有自己的調度算法,並且每個就緒隊列的調度相對獨立
- 優點:
- 親和性好
- 不需要加鎖
- 缺點:
- 負載不均衡
- 策略:‘偷’進程