1. 程式人生 > >Linux常見的進程調度算法

Linux常見的進程調度算法

處理器 適合 維護 body 服務器 的確 不同 然而 對數

進程調度:在操作系統中調度是指一種資源分配。

調度算法是指: 根據系統的資源分配策略所規定的資源分配算法。

操作系統管理了系統的有限資源,當有多個進程(或多個進程發出的請求)要使用這些資源時,因為資源的有限性,必須按照一定的原則選擇進程(請求)來占用資源。這就是調度。目的是控制資源使用者的數量,選取資源使用者許可占用資源或占用資源。

那麽我們看一下常見的進程調度算法:

1. 先來先去服務:

概念:

如果早就緒的進程排在就緒隊列的前面,遲就緒的進程排在就緒隊列的後面,那麽先來先服務(FCFS: first come first service)總是把當前處於就緒隊列之首的那個進程調度到運行狀態。也就說,它只考慮進程進入就緒隊列的先後,而不考慮它的下一個CPU周期的長短及其他因素。

要領:

按照進程進入就緒隊列的先後順序調度並分配處理機執行。先來先服務調度算法是一種非搶占式的算法,先進入就緒隊列的進程,先分配處理機運行。一旦一個進程占有了處理機,它就一直運行下去,直到該進程完成工作或者因為等待某事件發生而不能繼續運行時才釋放處理機。

(1)系統只要有按FIFO規則建立的後備作業隊列或就緒進程隊列即可,就是一個作業控制塊JCB或進程控制塊PCB加入隊列時加在相應隊列末尾。

(2)調度退出隊列時從相應隊列首開始順序掃描,將相關的JCB或PCB調度移出相應隊列。

流程圖:

技術分享圖片

執行過程:

技術分享圖片

優點:有利於長作業以及CPU繁忙的作業

缺點:不利於短作業以及I/O繁忙的作業

2. 短作業(進程)優先調度算法SJ(P)F

概念:對預計執行時間短的作業(進程)優先分派處理機.通常後來的短作業不搶先正在執行的作業.

優點:

比FCFS改善平均周轉時間和平均帶權周轉時間,縮短作業的等待時間;

提高系統的吞吐量;

缺點:

對長作業非常不利,可能長時間得不到執行;

未能依據作業的緊迫程度來劃分執行的優先級;

難以準確估計作業(進程)的執行時間,從而影響調度性能。

流程圖:

技術分享圖片

3. 輪轉法

概念:讓每個進程在就緒隊列中的等待時間與享受服務的時間成正比例。

定義:

時間片輪轉法類似於“輪流坐莊”的思想,條件是:各作業近似認為“同時”到達,題中條件是後面作業依次比前一個作業遲到一個時間單位,分析時要嚴格按照RR調度算法的實現思想:系統把所有就緒進程按先入先出的原則排成一個隊列。新來的進程加到就緒隊列末尾。每當執行進程調度時,進程調度程序總是選出就緒隊列的對首進程,讓它在CPU上運行一個時間片的時間。當進程用完分給它的時間片後,調度程序便停止該進程的運行,並把它放入就緒隊列的末尾。

流程圖:

技術分享圖片

4. 多級反饋隊列算法

概念:

設置多個就緒隊列,分別賦予不同的優先級,如逐級降低,隊列1的優先級最高。每個隊列執行時間片的長度也不同,規定優先級越低則時間片越長,如逐級加倍。

新進程進入內存後,先投入隊列1的末尾,按FCFS算法調度;若按隊列1一個時間片未能執行完,則降低投入到隊列2的末尾,同樣按FCFS算法調度;如此下去,降低到最後的隊列,則按“時間片輪轉”算法調度直到完成。

僅當較高優先級的隊列為空,才調度較低優先級的隊列中的進程執行。如果進程執行時有新進程進入較高優先級的隊列,則搶先執行新進程,並把被搶先的進程投入原隊列的末尾。

多級反饋隊列調度算法又稱反饋循環隊列或多隊列策略,主要思想是將就緒進程分為兩級或多級,系統相應建立兩個或多個就緒進程隊列,較高優先級的隊列一般分配給較短的時間片。處理器調度先從高級就緒進程隊列中選取可占有處理器的進程,只有在選不到時,才從較低級的就緒進程隊列中選取。

優點:

為提高系統吞吐量和縮短平均周轉時間而照顧短進程。

為獲得較好的I/O設備利用率和縮短響應時間而照顧I/O型進程。

不必估計進程的執行時間,動態調節。

流程圖:

技術分享圖片

幾種算法的比較:

技術分享圖片

那麽在我的linux下 采用什麽進程調度算法?

我們先看一下自己Linux的內核版本:

技術分享圖片

我們的內核版本為 2.6

所以 我們去查Linux 2.6進程調度算法

在LINUX 2.6中,有四種關於IO的調度算法,下面綜合小結一下:

1) NOOP
NOOP算法的全寫為No Operation。該算法實現了最最簡單的FIFO隊列,所有IO請求大致按照先來後到的順序進行操作。之所以說“大致”,原因是NOOP在FIFO的基礎上還做了相鄰IO請求的合並,並不是完完全全按照先進先出的規則滿足IO請求。NOOP假定I/O請求由驅動程序或者設備做了優化或者重排了順序(就像一個智能控制器完成的工作那樣)。在有些SAN環境下,這個選擇可能是最好選擇。Noop 對於 IO 不那麽操心,對所有的 IO請求都用 FIFO 隊列形式處理,默認認為 IO 不會存在性能問題。這也使得 CPU 也不用那麽操心。當然,對於復雜一點的應用類型,使用這個調度器,用戶自己就會非常操心。

2) Deadline scheduler
DEADLINE在CFQ的基礎上,解決了IO請求餓死的極端情況。除了CFQ本身具有的IO排序隊列之外,DEADLINE額外分別為讀IO和寫IO提供了FIFO隊列。讀FIFO隊列的最大等待時間為500ms,寫FIFO隊列的最大等待時間為5s。FIFO隊列內的IO請求優先級要比CFQ隊列中的高,,而讀FIFO隊列的優先級又比寫FIFO隊列的優先級高。優先級可以表示如下:
FIFO(Read) > FIFO(Write) > CFQ
deadline 算法保證對於既定的 IO 請求以最小的延遲時間,從這一點理解,對於 DSS 應用應該會是很適合的。

3) Anticipatory scheduler
CFQ和DEADLINE考慮的焦點在於滿足零散IO請求上。對於連續的IO請求,比如順序讀,並沒有做優化。為了滿足隨機IO和順序IO混合的場景,Linux還支持ANTICIPATORY調度算法。ANTICIPATORY的在DEADLINE的基礎上,為每個讀IO都設置了6ms
的等待時間窗口。如果在這6ms內OS收到了相鄰位置的讀IO請求,就可以立即滿足
Anticipatory scheduler(as) 曾經一度是 Linux 2.6 Kernel 的 IO scheduler 。Anticipatory 的中文含義是”預料的, 預想的”, 這個詞的確揭示了這個算法的特點,簡單的說,有個 IO 發生的時候,如果又有進程請求 IO 操作,則將產生一個默認的 6 毫秒猜測時間,猜測下一個 進程請求 IO 是要幹什麽的。這對於隨即讀取會造成比較大的延時,對數據庫應用很糟糕,而對於 Web Server 等則會表現的不錯。這個算法也可以簡單理解為面向低速磁盤的,因為那個”猜測”實際上的目的是為了減少磁頭移動時間。

4)CFQ
CFQ算法的全寫為Completely Fair Queuing。該算法的特點是按照IO請求的地址進行排序,而不是按照先來後到的順序來進行響應。
在傳統的SAS盤上,磁盤尋道花去了絕大多數的IO響應時間。CFQ的出發點是對IO地址進行排序,以盡量少的磁盤旋轉次數來滿足盡可能多的IO請求。在CFQ算法下,SAS盤的吞吐量大大提高了。但是相比於NOOP的缺點是,先來的IO請求並不一定能被滿足,可能會出現餓死的情況。
Completely Fair Queuing (cfq, 完全公平隊列) 在 2.6.18 取代了 Anticipatory scheduler 成為 Linux Kernel 默認的 IO scheduler 。cfq 對每個進程維護一個 IO 隊列,各個進程發來的 IO 請求會被 cfq 以輪循方式處理。也就是對每一個 IO 請求都是公平的。這使得 cfq 很適合離散讀的應用(eg: OLTP DB)。我所知道的企業級 Linux 發行版中,SuSE Linux 好像是最先默認用 cfq 的.

查看和修改IO調度器的算法非常簡單。假設我們要對sda進行操作,如下所示:
cat /sys/block/sda/queue/scheduler
echo “cfq” > /sys/block/sda/queue/scheduler

總結:
1 CFQ和DEADLINE考慮的焦點在於滿足零散IO請求上。對於連續的IO請求,比如順序讀,並沒有做優化。為了滿足隨機IO和順序IO混合的場景,Linux還支持ANTICIPATORY調度算法。ANTICIPATORY的在DEADLINE的基礎上,為每個讀IO都設置了6ms的等待時間窗口。如果在這6ms內OS收到了相鄰位置的讀IO請求,就可以立即滿足。

IO調度器算法的選擇,既取決於硬件特征,也取決於應用場景。
在傳統的SAS盤上,CFQ、DEADLINE、ANTICIPATORY都是不錯的選擇;對於專屬的數據庫服務器,DEADLINE的吞吐量和響應時間都表現良好。然而在新興的固態硬盤比如SSD、Fusion IO上,最簡單的NOOP反而可能是最好的算法,因為其他三個算法的優化是基於縮短尋道時間的,而固態硬盤沒有所謂的尋道時間且IO響應時間非常短。

2 對於數據庫應用, Anticipatory Scheduler 的表現是最差的。Deadline 在 DSS 環境表現比 cfq 更好一點,而 cfq 綜合來看表現更好一些。這也難怪 RHEL 4 默認的 IO 調度器設置為 cfq. 而 RHEL 4 比 RHEL 3,整體 IO 改進還是不小的。

Linux常見的進程調度算法