Linux內核設計與實現 第四章

Linux內核設計與實現  第四章

多任務

多任務系統可以劃分爲搶佔式多任務和非搶佔式多任務。進程在被搶佔之前能夠運行的時間叫時間片。Linux採用的就是搶佔式多任務

Linux的進程調度

IO消耗型進程:頻繁處於可運行狀態但是隻運行很短的時間。處理器消耗型:時間大多用在執行代碼上,系統儘量降低其調度頻率而延長運行時間。進程調度要在兩個調度之間尋求平衡:響應時間短和最大系統利用率。

優先級:根據進程價值和處理器佔用時間的分級方法。Linux採用了兩種不同的優先級範圍。第一種是nice值(-20到+19),默認是0:越大nice值則優先級越低,獲得的處理器時間越少,在Linux中,nice值表示的是時間片的比例。第二種是實時優先級,範圍是0~99,實時優先級越高表示進程優先級越高。

調度算法

unix進程調度中nice值的問題:(1)nice=0的往往是io進程,不需要太多時間片,nice=19的反而是CPU進程,需要更多時間片(2)nice爲0和1時分到的時間片相差無幾,但是nice爲18和19時分到的時間片相差一倍(3)需要分配一個絕對時間片,這將引發一系列問題(4)某些時間片用完的進程該不該再次上CPU,難以保證公平

CFS(公平調度):進程獲得CPU的時間由相對的nice值決定;nice值對應的使用時間不是絕對值,而是處理器使用比。

Linux調度的實現

時間記賬:操作系統需要對每個進程的時間進賬進行維護,CFS使用sched_entity調度器實體進行維護,它作爲一個成員變量se嵌入在進程描述符task_struct內。比較重要的一個概念就是vruntime虛擬實時,它描述的不是運行時間,而是運行時間的標準化。例如操作系統中有兩個進程,每個進程所需運行時間分別是20ms和80ms,剛開始,vruntime都是0,在運行10ms後,前者的vruntime是50ms,而後者的vruntime則爲25ms。如我們所見,vruntime是每個進程的實際運行時間對總進程數的標準化。

進程選擇:根據上面所述,顯然我們每次都應該選擇vruntime最小的進程,問題就在於我們如何找到這個進程——答案就是紅黑樹。具體細節不做過多描述。

調度器入口:schedule()。找到優先級最高的調度類,此調度類有一個自己的可運行隊列,從中選出最高優先級的進程。

休眠:休眠有兩種狀態:能被信號喚醒的和不能被信號喚醒的,這兩種狀態都是通過同一個等待隊列上,等待隊列存在的形式是鏈表。進程通過執行下列步驟將自己放入隊列:(1)創建等待隊列項。(2)加入隊列。(3)改變自己的狀態。(4)信號喚醒進程,進程進入“迷糊”狀態。(5)“迷糊”狀態的進程再次檢查條件,若真,則退出等待隊列,否則繼續睡。

喚醒:調用wake_up(),設置進程狀態,調用enqueue_task()將進程放入紅黑樹。需要注意的是存在虛假的喚醒,需要用一個循環保證其等待條件真正達成。

進程上下文切換

context_switch()

schedule():虛擬內存的切換switch_mm(),處理器切換switch_to()。need_resched()來檢查是否要重新進行調度。當進程應該被搶佔時,此標誌會被設置。搶佔分爲用戶搶佔和內核搶佔。

實時調度

被實時調度器管理,而不是CFS調度器

SCHED_FIFO:不使用時間片,先入的任務執行到完畢纔開始下一個,優先級比所有的SCHED_NORMAL高,只有更高優先級的SCHED_FIFO和SCHED_RR能搶佔。

SCHED_RR:與SCHED_FIFO基本一致,唯一不同的是相同優先級的會基於時間片輪流運行。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章