現代操做系統的調度

一. 操做系統調度的原則html


1. 什麼是調度
當計算機系統死多道程序設計系統時,一般就會有多個進程或者線程競爭CPU,只要有兩個或者更多的進程處於就緒狀態,這種狀況就會發生,若是隻有一個CPU能夠用,那麼必須選擇下一個要運行的進程,在操做系統中,完成選擇工做的這一部分被稱爲調度程序(scheduler)。該程序使用的算法稱爲調度算法(scheduler algorithm)。
 
幾乎全部的進程的I/O請求或者計算都是交替突發的,注意,某些I/O活動能夠看作是計算,例如,當CPU向視頻RAM複製數據以等待更新屏幕時,由於使用了CPU,因此是計算活動,而不是I/O活動,按照這種觀點,當一個進程等待外部設備完成工做而被阻塞時,纔是I/O活動。
Fig 1 : CPU調度的突發使用和等待I/O的交替出現:a) CPU密集型進程;b)I/O密集型進程
 
2. 什麼時候調度 
  • 在建立一個新進程後,須要決定是運行父進程仍是子進程,須要決定是運行父進程仍是子進程
  • 一個進程退出後必須進行調度
  • 在一個進程阻塞在I/O和信號量上或者因爲其餘緣由阻塞的時候,必須選擇另外一個進程開始運行。
  • 在一個I/O發生中斷的時候,必須作出調度決策。
    
  • 非搶佔式調度:挑選一個進程,而後讓該進程運行到被阻塞。
  • 搶佔式調度:挑選一個進程讓他運行到某個固定時段的最大值。若是在改時間段結束時,該進程仍然在裕興,它就會被掛起,而調度程序挑選另外一個進程運行,若是存在一個就緒進程。進行搶佔式調度處理,須要在事件間隔的末端發生時鐘中斷,以便把CPU控制返回給調度程序,若是沒有可用的時鐘,那麼非搶佔式調度就是惟一的選擇。
 
3. 調度算法的三個目標
  • 吞吐量 (throughout) : 系統每一個小時完成的做業數量。
  • 週轉時間 (turnaround time) : 一個批處理做業提交時刻到完成該做業完成時刻爲止的統計平均時間。
  • CPU利用率 (CPU Utilization) : 多用於度量批處理系統,反應CPU的使用狀況
 
固然咱們也能夠不徹底依靠操做系統的調度進程來對咱們的進程進行調度,咱們能夠手動調整,即調整調度程序的參數。這種方法被稱爲把調度機制與調度策略分離。
 
二. 批處理系統中的調度

對於批處理系統的調度,須要知足如下幾個要求:
  • 吞吐量——每小時最大做業量
  • 週轉時間——保持從提交到終止間最小忙碌
  • CPU利用率——始終保持CPU忙碌
 
1. 先來先去服務 (first-come first-served, FCFS)
這是一個非搶佔式的調度算法。實現也很簡單,就是進程按照它們請求的CPU順序使用CPU,誰先申請誰就會在隊列的前面,後面申請的就不斷加入到隊尾便可。當一個正在運行的進程發生了阻塞,那麼隊列中的第一個進程就會繼續運行,在阻塞的進程編程就緒時,就像一個新來到的做業同樣,排到隊列的末尾。
 
 
2. 最短做業優先 (shortest job first)
一樣也是一個非搶佔式調度算法。實現起來也很是簡單,就是把做業的時間從小到大排列,而且按這個順序進行進程的運行。但要注意,這個算法要當全部的進程均可以同時運行的時候纔是最優的。好比有4個做業ABCD(假設度能夠同時運行),他們的做業時間分別是1,2,4,8,咱們按照ABCD的順序進行進程的調度便可得最優的平均週轉時間。
 
 
注意平均週轉時間的計算方法 (k a0 + (k - 1) a1 + (k - 2) a2 ... +)/k,其中a0,a1,a2...分別是第k個做業運行的時間,好比上述例子的最優平均週轉時間爲 (4*1+3*2 + 2*4 +8)/4 = 6.5 
 
看成業不能同時運行時,最短做業優先算法不必定是最優的,好比如今有5個做業,從A到E,運行時間分別是2,4,1,1和1,他們的到達時間是0,0,3,3和3,開始的時候咱們只能選擇A或者B運行,由於其餘三個做業尚未到達,使用最短做業優先。將按照ABCDE的順序開始運行,其平均等待時間是6.4,可是按照BCDEA的順序運行做業,其平均的等待時間則是6。
 
 
3. 最短剩餘時間優先 (shortest remaining time next)
這個算法是最短做業優先算法的搶佔式的版本,使用這個算法的時候,調度程序老是選擇則剩餘運行時間最短的那個進程運行。再次提醒,有關的運行時間必須提早掌握。當一個新的做業到達打的時候,其整個時間同當前進程的剩餘時間進行比較。其進程的運行時間必須被提早知道,當一個新的做業到達的時候,其整個時間同當前進程的剩餘時間做比較。若是較新的進程比當前運行的進程須要更少的時間,當前進程就會被掛起,而運行新的進程。這種方式可使新的短做業得到良好的服務。
 
 
 
三. 交互式系統中的調度

1. 輪轉調度
最古老,最簡單,最公平並且使用最廣的算法是輪轉調度。每一個進程被分配一個時間片(quantum),即容許該進程在該時間段中運行,若是時間片結束時該進程還在運行,則剝奪CPU並分配給另一個進程。若是該進程在時間片結束前阻塞或者結束,則CPU馬上進行切換。以下圖所示:
 Fig 2:輪轉調度:a) 可運行進程列表;b) 進程B用完時間片後的可運行進程列表
時間片長度的設置在輪轉調度裏面很是重要,由於從一個進程切換到另外一個進程是須要必定的時間的——包括保存和裝入寄存器的值以及內存映像。更新各類表格和列表,清除和從新調入內存高速緩存等。進程切換有時候也被稱爲上下文切換。時間片設置得過短會致使過多的進程切換。下降了CPU的效率;而設置得太長又會可能對短的交互請求的響應時間變長。
 
2. 優先級調度
輪轉調度隱含的假設是全部的進程都是相同的優先級的,經過動態地或者靜態地對進程設立優先級,咱們能夠實現優先級調度,優先級高的進程優先運行。
 
爲了防止高優先級的進程無休止地運行下去,調度程序能夠在每一個時鐘週期結束時下降當前進程的優先級。若是這個動做致使該進程的優先級低於次高優先級的進程。則進行進程切換。一個可採用的方法是,每一個進程能夠賦予一個容許運行的最大時間片。當這個時間片用完時,下一個次高優先級的優先級進程能夠得到機會運行。
 
靜態優先級能夠經過預先評估進程的重要性來肯定。而動態優先級的肯定能夠按照如下的方法進行處理:
  
Fig 3:有4個優先級類的調度算法
上圖的算法一目瞭然,就是把全部的進程分爲四個優先級組,而在各種進程的內部採用輪轉調度。如圖3,只要存在優先級爲4的進程,則不會理會優先級3,2,1的進程。當優先級4的隊列爲空後,纔開始調度優先級3的進程。以此類推。
 
動態優先級調度要每隔一段時間調整進程的優先級,不然會發生飢餓。同時也要注意鎖封護和優先級反轉的問題
 
 
3. 多級隊列
多級隊列實現的思想和優先級調度的思想相似,可是增長給不一樣優先級的分配不一樣的時間片。越低優先級分配的時間片越大,而且當一個進程用完被分配的時間後,會被下降一個優先級。這樣能夠有效地讓短的交互進程讓出CPU。 而對於那些剛開始運行一段時間,然然後來又須要交互的進程,爲了不被永遠地懲罰。某些操做系統提供手動提升優先級的策略(好比按下F鍵能夠提高優先級)。
 
 
4. 最短進程有限
若是咱們把每一條執行的指令都看作是一個獨立的 「做業」,那麼咱們就能夠利用批處理系統的一個思想 「最短做業經常伴隨着最短響應時間」,對進程的過去進行推測,並執行估計運行時間最短的那一個。假設某個終端上每條命令的估計運行時間爲T0,如今假設測量到其下一次運行時間爲T1。能夠用這兩個值的加權和來改進估計時間。即aT0 +  (1 - a)T1。經過選擇a的值,能夠決定是儘快忘記老的運行時間,仍是在一段唱的時間內記住他們。當a = 1/2時,能夠獲得以下序列:
T0 T0/2 + T1/2T0/4 + T1/2 + T2/2T0/8 + T1/8 + T2/4 + T3/2
能夠看到三輪事後,T0在新的估計值中所佔的比重降低到1/8,這樣的算法被稱爲是老化 (aging) 。
 
 
5. 保證調度
保證調度是一個理想的調度,很難被實現。其基本實現思想是系統跟蹤每一個進程自建立以來已使用了多少CPU時間。而後它計算各個進程應該得到的CPU時間。即自建立以來的時間除以n,因爲各個進程實際得到的CPU時間是已知的。因此很容易計算出真正得到的CPU時間和應該得到的CPU的時間之比。比率爲0.5說明一個進程只得到了應得時間的一半,而比率爲2.0則說明它已經得到了應得時間的兩倍。(理想狀況是,在一個有n個進程的單用戶系統中,若全部的進程都等價。則每一個進程將得到1/n的CPU時間)。
 
 
6. 彩票調度
彩票調度的基本思想是向進程提供各類系統資源(如CPU時間)的彩票,一旦須要做出一項調度決策的時候,就隨機抽出一張彩票,擁有該彩票的進程得到該資源。在應用到CPU調度時候,系統能夠掌握每秒鐘50次的一種彩票,做爲獎勵每一個獲獎者能夠獲得20ms的CPU時間。
 
彩票調度能夠很簡單地實現優先級調度——只要讓每一個進程的彩票配額不同就能夠了,有更多彩票的進程得到CPU的概率要更大一點。同時進程間也能夠進行彩票交換,好比當一個進程請求IO而被阻塞時,它能夠把彩票讓給另外一個進程,讓另外一個進程得到更大的獲得CPU的概率。
 
 
7. 公平分享調度
咱們上面所考慮到的調度算法都是針對單用戶的。好比用戶一有9個進程,而用戶2有1個進程,假設咱們進行輪轉調度,那麼用戶1能夠得到90%的CPU的時間,可是用戶2只能得到10%的CPU時間。在多用戶的系統必須考慮不一樣用戶的CPU的時間分配。
 
 
 
四. 實時系統中的調度

實時系統是一種時間起着主導做用的系統。最典型的就是多媒體實時系統,當咱們在播放CD時,必須在很是短的時間內將流轉換成音樂,若是轉換時間過長,那麼音樂就會產生問題。實時系統一般能夠分爲硬實時和軟實時,前者的含義是必須知足絕對的截止時間,後者的含義是雖然不但願偶爾錯失截止時間,可是還能夠容忍。
 
實時系統中的時間能夠按照響應方式進一步分類爲週期性(以規則的時間間隔發生)事件或者非週期(發生時間不可預知)事件。一個系統可能要響應多個週期性的事件流,系統可能沒法響應全部事件。實時系統可調度的條件:(有m個週期事件,事件i以週期Pi發生,並須要Ci秒CPU時間來處理事件),知足這個條件的實時系統被稱爲可調度的。
 
在實時系統中咱們能夠嘗試設置一個主控時鐘,該時鐘每秒滴答適當的次數,例如針對NTSC制式的視頻,每秒滴答30次,在時鐘的每個觸發下,全部的進程都以相同的次序相繼運行,當一個進程完成其工做時,它將發出suspend系統調用釋放CPU直到主控時鐘再次觸發。當主控時鐘再次響應,全部的進程再次以相同的次序運行。只要進程數較少,全部的工做均可以在一幀的時間內完成。採用輪轉調度就能夠了。可是模型至關不靠譜,由於不一樣的進程可能以不一樣的頻率運行,具備不用的工做量,而且具備不一樣的最終時限。
 
 
Fig 4:三個週期性的進程,每一個進程播放一部電影,每一部電影的幀率以及每幀的處理需求有所不一樣
 通常實時調度模型:多個進程競爭CPU,每一個進程有本身的工做量和最終時限。假設系統知道每一個進程必須以什麼樣的頻率運行,有多少工做要作以及下一個最終時限是什麼。多個相互競爭的進程,其中若干進程或者所有進程都必須知足的最終時限的調度稱爲是實時調度。
 
1. 速率單調調度(實時靜態算法)
速率單調調度算法(Rate Monotonic Scheduling,RMS)能夠用於知足如下條件的進程:
  • 每一個週期性進程必須在其週期內完成。
  • 沒有進程依賴於任何其餘進程。
  • 每個進程在一次突發中須要相同的CPU時間量。
  • 任何非週期進程都沒有最終時限。
  • 進程搶佔時刻發生而沒有系統開銷。(理想模型)
單調速率算法按照如下規則給進程設立優先級:好比A進程每30ms運行一次,則每秒運行33次,則得到優先級33;B進程每秒運行20次,則得到優先級20,因此優先級與速率成線性關係,這就是這個算法的名字的來歷。RMS算法是最優的實時靜態算法中。
 
可是要注意的是,RMS算法並非在什麼狀況下都能正常運行的,下面會有一個RMS算法不能調度的情形。
Liu和Layland證實了在任何週期性進程系統,若是:則RMS能夠正常工做,隨着m->無窮,那麼最大利用率就會逼近ln2。好比當m=3時,最大容許利用率爲0.780,因此在三個週期性進程的系統中,當CPU利用率小於0.780,那麼RMS總能夠工做的,可是反過來講,若是CPU利用率大於0.780,並不能說明RMS不能工做(對於特定的週期和運行時間能夠的調度成功)。    
 
2. 最先最終時限調度(實時動態算法)
最先最終時限優先算法(Earliest Deadline First,EDF)是一個動態算法,它不要求進程是週期性的,也不要求每一個CPU突發具備相同的運行時間。只要有一個進程須要CPU時間,它就宣佈它的到來和最終時限。調度程序維持一個可運行的進程列表,該列表按最終時限排序,EDF算法運行列表中的第一個進程,也是具備最近最終時限的進程。當一個新的進程就緒時,系統進行檢查以瞭解其最終時限是否發生在當前運行的進程結束以前。若是是這樣,那麼新的進程就搶佔當前正在運行的進程。
 
EDF算法對於任何一組可調度的進程老是能夠工做的。
 
Fig 5:RMS和EDF調度實例1
在上述例子中,RMS和EDF算法均可以正常調度,對於RMS算法,前80ms的都是很好理解的,由於優先級A>B>C(A的優先級是33,B是25,C是20),因此咱們只用把ABC三個進程輪轉調度便可。注意A能夠搶佔B,B能夠搶佔C,因此在90ms的時候,A和B都處於就緒態,可是A的優先級要比B要高,因此A會搶佔B,當A運行完之後,繼續運行C。
 
而對於EDF算法,在前90ms中,與RMS算法的處理結果都是同樣的,然而在90ms時,A和B選擇的最終時限都是同樣的,可是EDF算法規定,噹噹前運行的進程和其餘進程的最終時限同樣時,不搶佔當前運行的進程,防止而外的開銷,因此B繼續運行,而後B運行完之後調度A。
 
Fig 6:RMS調度失敗的例子
如今咱們換一個例子,假設A進程每一個週期運行15ms,而不是10ms,這個時候RMS算法就會調度失敗了,首先在RMS算法中,ABC的優先級不變,由於RMS算法中的優先級只與進程的運行頻率有關,而與進程的運行時間是無關的。在t = 45ms的時候,調度B,而因爲C的優先級低於B,因此C沒法搶佔B而錯過其最終時限。RMS算法調度失敗。
 
如今咱們來看EDF算法,當t = 30時,A,B和C發生競爭,而這個時候A的最終時限是60,B的最終時限是80,而C是50,因此調度算法決定調度C進程,當C進程運行完後其最終時限變爲100,因此調度算法調度A,以此類推。當t = 90時,也發生了剛纔A和B發生競爭的狀況,EDF選擇不切換進程,繼續運行B。
 
 
五. 線程調度

線程調度主要是分爲用戶級線程調度和內核級線程調度,他們的區別就是在於內核是否定識到有不一樣的線程,以下圖所示:
Fig 7: a)用戶級線程的可能調度,有50ms時間片的進程以及每次運行5ms CPU的線程 b) 擁有相同特徵的內核級線程的調度
對於用戶級線程,CPU給一個進程分配CPU後,由進程在用戶空間上控制線程的調度,這種調度不會影響其餘進程,當這個進程的時間片用完後,內核會調度其餘進程。而對於內核級線程,它不用考慮被調度的線程是屬於哪一個進程的。這個時候時間片是線程擁有的。
 
用戶級線程和內核級線程的性能是有差異的。通常來講用戶級線程的切換很是輕鬆。可是對於內核級線程,線程切換須要保存完整的上下文,修改內存映像,使高速緩存失效等操做。這些操做是費時的。
相關文章
相關標籤/搜索