linux核心學習筆記(六)進程調度

來源:互聯網
上載者:User
Linux 核心筆記 – 進程調度

關鍵詞: Linux    核心    進程調度                                          

 

Linux 核心筆記 – 進程調度

原文連結:

http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=linuxK&Number=294463&page=5&view=collapsed&sb=5&o=all

Linux 核心筆記 – 進程調度

1      前言
2      調度演算法
2.1.1        常用概念
2.1.2        進程資料結構中相關內容
2.1.3        調度演算法說明
2.1.4        相關函數
3      發送器的執行
3.1.1        直接調用
3.1.2        延遲調用
3.1.3        相關函數
4      進程調度
5      SMP系統的調度
6      問題與答案
7      參考文獻

1        前言
本文的許可協議遵循GNU Free Document License。協議的具體內容請參見http://www.gnu.org/copyleft/fdl.html。在遵循GNU Free Document License的基礎上,可以自由地傳播或發行本文,但請保留本文的完整性。
歡迎大家對這篇文章提出意見和指正,我的email是:shisheng_liu@yahoo.com.cn。

2        調度演算法
2.1.1        常用概念
2.1.1.1            定時中斷
    通過硬體的可程式化插斷控制器8254來實現,定時中斷髮生的頻率由HZ定義,發生的時間間隔被稱為tick。
2.1.1.2            CPU節拍(tick)
電腦內部時間的一個計數單位,表示發生一次時鐘中斷的時間間隔。
2.1.1.3            HZ
 時鐘中斷髮生的頻率。在i386機器上,HZ被定義為100,因此時鐘中斷每10ms一次。
2.1.1.4            CPU時期
      調度是以CPU時期為周期的,在一個CPU時期/調度周期內,系統中所有程式都被執行直到用完當前的時間片,然後所有進程的counter值被重新計算,並開始另一個CPU時期。
2.1.1.5            進程的分類
在發送器看來,系統中的進程分為兩大類,分別是即時進程和普通進程。在任何時候即時進程的執行都高於普通進程。進程資料結構中的policy成員變數表示了進程是哪一類,而sched_set(/get)scheduler提供了控制進程調度policy的使用者級編程介面。
2.1.2        進程資料結構中相關內容
2.1.2.1               1.nice
    進程的優先順序,影響進程獲得CPU事件的多少,20為最低,-19為最高。
2.1.2.2            2.counter
 進程時間片所剩餘的CPU節拍數。初始值根據進程的nice值決定,在每次時鐘中斷髮生時,也就是一個CPU節拍(tick)的時候,當前進程的counter值減1,如果counter值變為0則表示當前進程的時間片已經用完,系統會重新調度,決定下一個執行的進程。
2.1.2.3            3.need_resched
  標誌位。該位在從中斷和系統調用中返回的時候被檢查,need_resched為1的時候表示要求啟動發送器,這通常發生在進程的時間片已經用完,或者因為IO事件發生而強行搶佔當前進程的時候。
2.1.2.4            4.policy
  進程的調度策略。如果調度策略為SCHED_RR或者SCHED_FIFO則表示當前進程為即時進程,否則(SCHED_OTHER)為普通進程。
2.1.3        調度演算法說明
Linux採用相當簡單但實際證明效果不錯的調度演算法。在調度的時候,所有正在運行進程的執行權值(goodness)都被計算,最終權值最高的進程獲得執行的機會。假設得到的最大權值為0,就認為本次CPU時期已經執行完畢,會重新計算所有進程的counter值,開始新的CPU時期。調度演算法的核心就是goodness的計算,計算的基本思路如下:
如果等待調度的進程是即時進程,它的goodness為1000 + 本身的優先順序,而普通進程的goodness遠小於1000,這就保證了即時進程總是優先於普通進程執行。
  如果進程剩餘的counter為0,就認為它已經用光了自己在該時期的CPU時間片,goodness返回0。
  對於其他的情況,用下面的公式來計算goodness:
goodness = counter + 20 – nice;
2.1.4        相關函數
1.schedule()  in kernel/sched.c
主調度函數,選擇要啟動並執行進程
2.goodness() in kernel/sched.c
由schedule()調用,計算進程的執行權值
3        發送器的執行
可以通過兩種方式來啟用發送器,分別是直接調用和延遲調用。
3.1.1        直接調用
   當current進程準備主動放棄CPU的時候,它會直接調用發送器schedule(),將CPU讓給另一個進程。
促使current進程主動放棄CPU的原因有兩種,一種情況是current需要睡眠(阻塞)來等待所需的資源準備好,此時current的狀態被設定為TASK_INTERRUPTABLE或TASK_UNINTERRUPTABLE,在調用schedule()後進程進入睡眠狀態;另一種情況下進程設定SCHED_YIELD的調度策略,然後調用schedule(),此時進程只是短暫的放棄CPU,在下一次schedule()被調用的時候進程會繼續參與CPU的競爭。
3.1.2        延遲調用
通過設定當前進程的need_resched標誌來在其後的某個時刻啟用發送器。前面說過,在從中斷/異常/系統調用中返回時,need_resched標誌被檢查,在標誌不為0的時候會啟用發送器。例如:當時鐘中斷髮生時,中斷處理常式檢查到當前進程的時間片已經執行完畢,它就會設定當前進程的need_resched標誌;另一個例子是當某個IO中斷髮生時,中斷處理常式發現有進程在等待該IO事件,它會將正在等待的進程的狀態變為執行態,並設定當前進程的need_resched標誌。當中斷處理常式結束[注1],系統會重新調度,在這種情況下,新轉入執行態的進程很可能會獲得執行機會,從而使系統保持對IO事件的快速響應。
[注1]:如果當前進程運行在核心態,即正在執行系統調用過程中,重新調度會延遲到當前進程的系統調用執行完畢才進行。
3.1.3        相關函數
  1.wake_up_common() in kernel/sched.c
   啟用IO等待隊列中的進程,它會順序調用try_to_wake_up(),reschedule_idle()等函數來要求對進程進程重新調度。
  2.do_timer() in kernel/timer.c
   定時時鐘中斷程式,減少當前進程的counter值,如果counter已經用完,則設定進程的need_resched域要求重新調度。
  3.ret_from_intr/sys_call/exception   in arch/i386/entry.S
  組合語言中的程式點,在從中斷/異常/系統調用中返回時都會執行這一段程式,檢查當前進程的need_resched域,如果不為0就會啟用schedule()重新調度。

4        進程調度
linux的進程調度1所示。

 
5        SMP系統的調度
SMP系統中的調度演算法的不同主要表現在調度演算法的最後,對於被切換出當前CPU運行權的進程調用了schedule_tail函數,目的是看能夠將它轉移到另一個CPU中運行。

6        問題與答案
Q.在當前系統下,調度時間片的長度是多少?
A. 與2.2.x版的核心相比,kernel2.4.x的時間片長度縮短了,對於最高優先順序的進程來說,時間片的長度為100ms,預設優先順序進程的時間片長度為60ms,而最低優先順序進程的時間片長度為10ms。
Q. Linux如何保證對I/O事件相對比較快的響應速度,這個響應速度是否與調度時間片的長短有關?
A.當I/O事件發生的是時候,對應的中斷處理常式被啟用,當它發現有進程在等待這個I/O事件的時候,它會啟用等待進程,並且設定當前正在執行進程的need_resched標誌,這樣在中斷處理常式返回的時候,發送器被啟用,原來在等待I/O事件的進程(很可能)獲得執行權,從而保證了對I/O事件的相對快速響應(毫秒級)。
    從上面的說明可以看出,在I/O事件發生的時候,I/O事件的處理進程會搶佔當前進程,系統的響應速度與調度時間片的長度無關。
Q.高優先順序(nice)進程和低優先順序進程在執行上有何區別?例如一個優先順序為-19(最高優先順序)的進程和優先順序為20(最低)的進程有何區別
A. 進程獲得的CPU時間的絕對數目取決於它的初始counter值,初始的counter的計算公式(sched.c in kernel 2.4.14)如下:
p->counter = (p->counter >> 1) + ((20 - p->nice) >> 2) +1)
由公式可以計算出,對於標準進程(p->nice 為0), 得到的初始counter為6,即進程獲得的時間片為60ms。
最高優先順序進程(nice為-19)的初始counter值為10,進程的時間片為100ms。
最低優先順序進程(nice為20)的初始counter值為1,進程時間片為10ms。
 結論是最高優先順序進程會獲得最低優先順序進程10倍的執行時間,普通優先順序進程接近兩倍的執行時間。當然,這是在進程不進行任何IO操作的時候的資料,在有IO操作的時候,進程會經常被迫睡眠來等待IO操作的完成,真正所佔用的CPU時間是很難比較的。
我們可以看到每次重新計算counter的時候,新的counter值都要加上它本身剩餘值的一半,這種獎勵只適用於通過SCHED_YIELD主動放棄CPU的進程,只有它在重新計算的時候counter值沒有用完,所以在計算後counter值會增大,但永遠不可能超過20。
Q.進程是否可能在執行系統調用的過程中被搶佔?
A.進程在執行系統調用的過程中不會被搶佔。讓我們設想進程a正在執行的過程中發生中斷,而中斷處理常式判斷出系統需要被重新調度,它會設定進程a的need_resched標誌(need_resched標誌的作用參見前面說明),在中斷處理常式結束之後(ret_from_intr),系統會檢查被中斷處理常式中斷執行的進程的優先順序,如果此時進程a處在使用者態,系統會直接啟用發送器完成進程切換;而如果此時進程a處在核心態,系統會不作調度而恢複進程a的執行,只有進程a完成系統調用之後(ret_from_sys_call),它的need_resched標誌才會被檢查,從而完成進程切換。
進程在核心態不會被搶佔的特點減少了單CPU系統中核心設計的複雜性,因為不需要考慮不同進程對核心代碼和資料結構的競爭。

7        參考文獻
1.  Linux核心原始碼版本2.4.14
在任何時候真實的代碼總是提供給我們最準確和詳細的資料。感謝Linus Torvalds,Alan Cox和其它linux開發人員的辛勤勞動。
2.DANIEL P.BOVET & MARCO CESATI
  <> ISBN: 0-596-00002-2  O’REILLY 2001
  中譯版 《深入理解Linux核心》 陳莉君等譯 ISBN: 7-5083-0719-4 中國電力出版社 2001。
本書是專門介紹linux核心結構的書中最詳盡的一本,對程式碼分析講解的也比較深入,基於2.2的核心版本
3.W.Richard Stevens
 《UNIX環境進階編程》 尤晉元譯 ISBN: 7-111-07579-X   機械工業出版社 2000
  UNIX編程聖經,程式員手頭必備的書籍之一,對所有UNIX開發人員,無論水平高低,都有參考價值。翻譯的水準也難得一見的高明。 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.