OS中的算法
討論順序按CPU<->內存<->磁盤的順序展開,
CPU<->內存:主要對象是作業和進程,發生調度的場景是CPU和內存,偶爾涉及到外存。
內存<->磁盤:主要對象是數據,發生調度的場景是內存和磁盤
CPU調度
三種調度方式
面向作業,進程,CPU和內存分爲三種
高級調度
又稱作業調度,是將作業從外存中調入內存,將作業處理完後再把作業從內存調至外存,作業的調入調出只會發生一次
中級調度
又稱內存調度,面向進程,當內存空間不足時,OS會把暫時不能運行的進程調至外存等待,此時的進程稱爲掛起態,注意這個時候進程映像被調至外存,但是進程的PCB仍然存在於內存中
低級調度
又稱進程調度,是在內存中的調度,按照進程調度算法從就緒隊列中選擇一個進程將CPU的資源分配給它。
三種調度 | 發生頻率 | 調度對象 | 涉及位置 |
---|---|---|---|
作業調度 | 低 | 作業 | 內存——外存 |
內存調度 | 中 | 進程 | 內存——外存 |
進程調度 | 高 | 進程 | 內存 |
調度的時機
不能進行調度的情況:
- 處理中斷
- 進程在OS內核程序臨界區
- 其它需要完全屏蔽中斷的原子操作
可以進行進程調度的情況:
- 進程時間片用完
- 進程發出中斷指令切換到阻塞態
- 進程無法繼續執行時
補充說明:
臨界資源是指在同一時間只能有一個進程訪問的資源,比如說輸入機,打印機等等,臨界區是訪問臨界資源的代碼段,進程準備進入臨界區之前需要檢查是否有其它進程在使用這個資源,如果有則阻塞自己,如果沒有則進入給臨界資源加鎖並且進入臨界區,退出臨界區時進程會解鎖以便其它進程訪問。
進程調度
前面提到,CPU的進程調度會根據一定算法從就緒隊列中選擇一個進程來執行,那麼這個算法就涉及到進程調度
有關進程調度的基本概念
-
長作業,短作業,運行時間長的稱爲長作業,運行時間短的成爲短作業。一般CPU繁忙型進程由於需要使用長時間的CPU資源,所以它是長作業,而IO繁忙型進程只需要得到CPU然後發出I/O請求就可以做別的事了,索引它是短作業。、從性能上來說,CPU應該優先滿足短作業,再滿足長作業。
-
優先級
優先級別高的進程會更先使用CPU,進程可以按照優先級分爲
系統進程>非系統進程
交互型>非交互型
I/O型>非I/O型
-
搶佔式,非搶佔式,當一個進程使用CPU資源的時候,其它進程只能等待它使用完成才輪到自己使用,這種方式就要非搶佔式,與之相對應的是搶佔式,當其它進程需要使用CPU的時候OS可以剝奪當前正在運行的進程的CPU資源提供給新的進程使用。
-
衡量調度算法的指標
- 週轉時間=完成時間-到達時間
- 平均週轉時間=總的週轉時間/作業數
- 帶權週轉時間=週轉時間/實際運行時間
- 平均帶權週轉時間=總的帶權週轉時間/作業數
- 等待時間,指進程等待處理機資源的時間
- 響應時間,指用戶提交請求到系統首次產生響應所用的時間
- CPU利用率=CPU運行時間/總時間
- 系統吞吐量,指單位時間內CPU完成作業的數量
算法
FCFS先到先來服務
按照進程到達時間先後順序執行,先到達的進程先服務
SJF短作業優先
顧名思義,運行時間短的進程優先執行
優先級調度算法
其中可以分爲搶佔式和非搶佔式,按照一定規則使得優先級別高的進程先運行,這種調度算法會飢餓
HRRN高響應比優先
比較優秀的一個算法,兼顧了短作業優先並且讓長作業不會飢餓
響應比計算方法是:
RR(Round-Robin)時間片輪轉
不會飢餓,適用於多用戶系統
時間片過長會退化成FCFS,時間片過短,性能會下降
多級反饋隊列
同樣是解決了短作業,長作業算法的缺點的算法,進程不會飢餓
總結
算法 | 思想 | 優點 | 缺點 | 是否飢餓 | 適用於 | 特點 |
---|---|---|---|---|---|---|
FCFS | 按序服務 | 不會飢餓 | 對短作業(I/O型)不好 | 否 | CPU型作業頻繁 | 有利於長作業,不利於短作業;算法簡單,效率低 |
SJF | 所花時間短的先服務 | 會飢餓 | 對長作業(CPU型)不好 | 是 | I/O型作業頻繁 | 對長作業不利。平均等待時間和平均週轉時間最少(不考慮飢餓的話性能最優) |
優先級 | 優先級別高的先服務 | 緊急任務可以優先使用CPU | 飢餓 | 是 | 任務有緊急性,需要較快響應的系統,終端型作業和短作業 | 衍生算法多,有搶佔式和非搶佔式兩種,同時可以動態調整優先級避免產生飢餓 |
HRRN | 響應比高的進程先服務 | 兼顧了長作業和短作業 | 無明顯缺點 | 否 | 短作業響應比天然高,長作業由於等待時間長響應比也會升高從而不會飢餓 | |
RR | 按照時間片來分配進程資源 | 分時系統最適合的算法 | 無明顯缺點 | 否 | 多用戶系統,分時系統 | 時間片的選取很關鍵,時間片長則退化成FCFS,時間片短則頻繁切換進程開銷過大 |
多級反饋隊列 | 優先級隊列+時間片輪轉 | 終端型:短作業優先。短作業:週轉時間短。長作業不會飢餓 | 無明顯缺點 | 否 | 可以衍生出很多算法 |
內存調度
內存中引入非連續分配時,由於發生缺頁的時候要根據一定算法選擇換入,換出的頁,因此有了專門的調度算法,在講算法之前,先說一下操作系統劃分內存的分配方式,重點關注的是調頁算法
操作系統內存的分配方式有兩種,一種是連續分配,另一種是非連續分配
連續分配
連續分配是指一個進程的數據存放位置必須是連續的
-
單一連續分配
整個內存只分配給一個進程,用於早期的操作系統。注意只有這種分配方式是給一道進程的,其它都是給多道進程的
-
固定分區分配
將內存劃分爲固定分區,每個進程裝入適合的分區中
因爲一開始就劃分好了分區,所以稱爲固定分區
分區方式有兩種:
- 分區大小不變
- 分區大小可變
-
動態分區分配
一開始並不劃分分區,而是根據進程運行時動態的調整分區大小,當一個進程裝入時根據算法裝入合適的位置
分區分配算法主要有這幾種
-
BF(best fit)最佳適應
算法選擇一個最合適的內存空間裝入,此算法需要維護一個存儲內存空間大小的鏈表,從小到大排序,因此這個算法需要額外的時間和空間去維護鏈表
-
WF(worst fit)最壞適應
總是選擇一個最大的內存空間裝入,此算法同樣要維護一個從大到小排序的鏈表,需要額外的時間和空間
-
FF(first fit)首次適應
選擇一個第一次能滿足進程所需空間大小的內存塊裝入。由於裝入發生在低地址段的頻率較高,所以低地址處會有許多碎片
-
NF(next fit)鄰近適應
FF的改進版,從上一次比較的位置開始尋找內存塊,而不是從頭開始尋找內存塊。NF會造成大的內存空間分裂成小碎片。
以上四種算法FF性能最好,BF和WF性能都很差
算法之間的比較
名詞 性能 額外空間 特點 BF 差 有序鏈表 留下很多小碎片(外部碎片) WF 差 有序鏈表 大塊的內存被分割了 FF 最優 無 低地址處留下很多碎片,增加了查找時間 NF 還可以 無 把大空間分割了 大塊的空間被分割是很可惜的事情,因爲可能找不到空間裝入某些大進程
很多的小碎片也很麻煩
-
上述三種分區方法的比較(注意這裏始終是連續分配方式下的不同分區方法)
名稱 | 碎片類型 | 支持進程 | 特點 |
---|---|---|---|
單一連續分配 | 內 | 一個 | 唯一採用覆蓋和交換的分配方式,用於早期的操作系統 |
固定分區分配 | 內 | 多個 | 不能實現多進程共享存儲區,內存利用率低 |
動態分區分配 | 外 | 多個 | 會產生很多小的碎片 |
非連續分配
特別重要的一個知識點
-
頁式
將內存分成固定大小的分區,每一個分區稱之爲頁框/頁幀/內存塊/物理塊(內存塊的說法貼切)
需要一個索引表來指向分區,索引表的內容就是塊號,索引表稱爲頁表,索引表中的項稱爲頁表項
用戶程序也按頁分,這裏的每一頁對應內存中的一個內存塊
-
段式
將內存分爲長度不等的段,此時索引表的內容是(段長,起始地址)
段式比頁式更方便的實現數據和信息共享
-
段頁式
先分段,再分頁
名詞 | 碎片類型 | 索引表內容 | 特點 |
---|---|---|---|
頁式 | 內部 | 塊號 | 最常用 |
段式 | 外部 | 段長,內存中起始地址 | 更方便的實現數據和信息共享 |
段頁式 | 內部 | 段長,頁表中起始地址;塊號 | 結合兩者優點 |
缺頁置換算法
OPT最佳置換算法
思想:每次發生缺頁時,從當前時刻向後看,找到當前內存中最後使用的頁,然後置換
例如
塊號\訪問頁號 | 2 | 3 | 1 | 4 | 1 | 4 | 3 | 2 |
---|---|---|---|---|---|---|---|---|
1 | 2 | 2 | 2 | 4 | 2 | |||
2 | 3 | 3 | 3 | 3 | ||||
3 | 1 | 1 | 1 | |||||
是否缺頁 | ✔ | ✔ | ✔ | ✔ | ✔ |
9次訪問,共缺頁5次,最後一次缺頁隨機選擇一個頁換出即可
請注意:OPT算法由於需要缺頁之後的訪問順序,而os中無法知道進程執行過程中頁的訪問順序,所以OPT算法只是理論上的算法,無法實現
FIFO先進先出置換算法
思想:維護一個頁號隊列,每次發生缺頁時,置換隊首頁號
FIFO很直觀,但是會產生Belady異常,即:增加物理塊反而會增加缺頁次數,這是由於FIFO要使用隊列,而基於堆棧類的算法(LRU)不會產生Belady異常
LRU最近最久未使用置換算法
思想:每次發生缺頁時,從當前時刻往前看,找到當前內存中最久未使用的頁,然後置換
爲了模仿OPT而產生的算法,性能比較好,但是需要寄存器和棧的硬件支持,因此開銷比較大
CLOCK時鐘算法,又稱爲NRU最近未用算法
思想:增加修改位,按照順/逆時間遍歷所有的頁號,將符合要求的頁換出,下一次缺頁時從上次換入的頁開始遍歷
流程:
第一輪掃描,選擇未修改的頁置換,此時將掃描過的頁的修改位置爲0
重複第一輪掃描,總能找到一頁置換
CLOCK的改進型
思想:增加更多的標誌位,(訪問位,修改位)
假設(1,1)表示訪問,且有修改,(1,0)表示訪問但未修改
因爲修改過的頁要花更多的時間寫回磁盤,我們優先選擇未修改過的頁
又因爲根據局部性原理,訪問過的頁很有可能不久再被訪問,所以我們優先換出未訪問的頁。
流程:
第一輪掃描,選擇(0,0)的頁置換
第二輪掃描,選擇**(0,1)**的頁置換,也就是未被訪問但是被修改過的頁。此輪將掃描過的修改位改爲1
重複上述兩輪掃描,總是能找到一頁並置換
此算法換頁的淘汰順序是:(0,0) > (0,1) > (1,0) > (1,1)
請注意實際上不存在(0,1)的頁,也就是不存在未被訪問但是修改過的頁,這是算法執行過程中修改標誌位導致的
磁盤調度
爲什麼要磁盤調度?
因爲CPU要讀入數據,數據不在內存中,OS就從磁盤中讀取數據到內存中,磁盤中如何調度,按照什麼順序調度,就涉及到下面的算法
基本概念
磁盤的組成:磁頭,磁臂,盤片
解釋:磁頭讀取數據,磁臂負責移動磁頭,盤片存儲數據
盤片的組成:盤面,磁道,扇區(盤塊)
一個盤片有上下兩個盤面組成,一個盤面有多條磁道,磁道越多磁盤可以存儲的數據就越多,一個磁道可以等分爲多個扇區
所有盤片的同一磁道組成柱面
磁盤訪問時按照(柱面,盤面,扇區)的順序訪問
因爲移動磁臂的開銷很大,所以優先確保這個柱面上所有需要讀入的磁道都讀取入完了才 移動磁臂。然後保證同一個盤面沒有要讀入的內容了,再切換扇區
算法
FCFS,先來先服務算法
思想:按照請求序列,先來的先讀
SSTF 最短尋找時間優先
思想:總是優先滿足離磁頭最近的請求
特點:會飢餓
SCAN掃描算法,又稱電梯調度算法
規定磁頭移動方向,只有磁頭移動到一端後才反向移動
不會飢餓,但是由於靠近一端的請求序列會在短時間內掃過兩次所以對請求序列不公平
C-SCAN,循環掃描
規定磁頭移動方向,只有磁頭移動到一端後,才從另一端開始移動
LOOK,C-LOOK
LOOK對應SCAN
C-LOOK對應C-SCAN
帶有LOOK標識的,表示以上兩個算法的磁頭並不是嚴格的執行到另一端再返回,而是遇到該方向最後一個請求就開始反轉移動方向。
讀
SSTF 最短尋找時間優先
思想:總是優先滿足離磁頭最近的請求
特點:會飢餓
SCAN掃描算法,又稱電梯調度算法
規定磁頭移動方向,只有磁頭移動到一端後才反向移動
不會飢餓,但是由於靠近一端的請求序列會在短時間內掃過兩次所以對請求序列不公平
C-SCAN,循環掃描
規定磁頭移動方向,只有磁頭移動到一端後,才從另一端開始移動
LOOK,C-LOOK
LOOK對應SCAN
C-LOOK對應C-SCAN
帶有LOOK標識的,表示以上兩個算法的磁頭並不是嚴格的執行到另一端再返回,而是遇到該方向最後一個請求就開始反轉移動方向。