linux調度器(一)——概述

來源:互聯網
上載者:User

本次分析的kernel代碼為2.6.32-220。並且我們先不考慮SMP。當前linux的發送器由兩個調度器組成:主調度器,周期性調度器(兩者又統稱為核心調度器);並且每個調度器包括兩個內容:調度架構(其實質就是兩個函數架構)及調度器類。調度器類是實現了不同調度策略的執行個體,如 CFS、RT class。它們的關係如:


圖 調度器的組成

當前的核心支援兩種調度器類(sched_setscheduler系統調用可修改進程的策略):CFS(公平)、RT(即時);5種調度策略:SCHED_NORAML(最常見的策略)、SCHED_BATCH(除了不能搶佔外與常規任務一樣,允許任務運行更長時間,更好地使用快取,適合於成批處理的工作)、SCHED_IDLE(它甚至比nice 19還有弱,為了避免優先順序反轉使用)和SCHED_RR(迴圈調度,擁有時間片,結束後放在隊列末)、SCHED_FIFO(沒有時間片,可以運行任意長的時間);其中前面三種策略使用的是cfs調度器類,後面兩種使用rt調度器類。
         另外,對於調度架構及調度器類,它們都有自己管理的運行隊列,調度架構只識別rq(其實它也不能算是運行隊列),而對於cfs調度器類它的運行隊列則是cfs_rq(內部使用紅/黑樹狀結構組織調度實體),即時rt的運行隊列則為rt_rq(內部使用優先順序bitmap+雙向鏈表組織調度實體)。調度器相關的幾個資料結構的關係:


圖 調度器結構關係圖

    Rq表示調度架構上的運行隊列(它本身並沒有真正組織調度實體,而是它下面的cfs及rq兩個成員負責組織真正的調度實體),在多核處理器上每個cpu有一個rq結構.
rq#cpu運行隊列,每個cpu一個
nr_running:表示總共就緒的進程數(包括cfs,rq及正在啟動並執行)
cpu_load[]:表示該rq所在cpu的曆史load,一般有5個
load:表示當前cpu的load,這個load是它所有就緒進程的load之和(同樣包括cfs,rq及正在啟動並執行)
nr_swithces:進行環境切換的次數
cfs:該rq所包括的cfs_rq運行隊列,這個是所有cfs_rq的root

rt:與上面的cfs類似
curr:當前正在啟動並執行進程(這裡不是se,注意跟cfs_rq的curr區分開來)
clock:運行隊列的時鐘,這個時鐘是後面cfs,rq所使用的時鐘,也是大多數proc顯然的時間相關的時鐘
cpu:該rq所屬的cpu
leaf_cfs_rq_list:如果使用的cgroup來建立嵌套的group,那麼這個group的cfs_rq通過該變數組織,註:每個cgroup都有一個cfs_rq

cfs_rq#cfs調度器類的運行隊列
load:該cfs_rq的load,它只計算它本層下面的se的weight之和,並不是這個se的load,也不是遞迴到葉子節點上的所有se weight之和(理解這點非常重要),這裡有兩個概念要區分清楚:se的load與se的weight,之所以會有這兩個區別是因為組調度的存在,對於一個組它本身也是一個se,它也有一個cfs_rq,所以對於組它的se->weight其實就是我們設定cgroup的cpu.shares的一個均值(cpu.shares是儲存在tg->shares,而se->weight是通過update_cfs_shares計算出來的,如果它下面的se在一個cpu裡,那麼它們就相等,否則…還不清楚到底為什麼那樣算的?),而它的cfs_rq的load,則是它下面所有se的weight之和;對於普通的進程,則它本身沒有cfs_rq(它有所屬的cfs_rq),所以它沒有cfs_rq
load,只有weight
nr_running:就緒的進程數,只包括本層的(包括正在啟動並執行)
h_nr_running:只對於組才有效,包括底層所有cfs_rq的nr_running之和
exec_lock:該cfs_rq總共佔用的cpu時間(物理),只累計本層
min_vruntime:用於調整se的vruntime,它是遞增的,但不一定是該cfs_rq裡所有se最小
tasks_timeline:該cfs_rq的紅/黑樹狀結構root
rb_leftmost:紅/黑樹狀結構的最左邊節點
curr:當前啟動並執行se(對於組雖然它不會在cpu上運行,但是當它的下層有一個task在cpu上運行,那麼它所在的cfs_rq就把它當做是該cfs_rq上當前正在啟動並執行se)
rq:該cfs_rq當前所attach的cpu rq
tg:該cfs_rq所屬的task group,即所屬的組,通過該成員可以找到該cfs_rq對應的組在該cpu上所屬的se,即該cfs_rq自身的se

sched_entity#調度實體
load:調度實體自身的load,對於普通進程這個load跟優先順序成正比,優先順序高的,load大,通過prio_to_weight[]表可以尋找到它們的對應關係(注意與cfs_rq的load區分開)
run_node:紅/黑樹狀結構節點
on_rq:表示是否在運行隊列或正在執行(當前執行的進程是不儲存在紅/黑樹狀結構裡,但它的on_rq還是標誌著的,記住這個也很關鍵)
exec_start:這個並不是表示進程開始執行的時候,而是每次update_curr都會更新該時鐘為當前rq的clock,它主要用於計算上次執行update_curr到這次再執行,總共發的cpu clock,然後再把這個差值加到sum_exec_runtime
sum_exec_runtime:進程總共執行的cpu clock(佔用cpu的物理時間)
prev_sum_exec_runtime:上次該進程被調度時已經佔用的cpu時間(每次在調度一個新的進程時都會把它的se->prev_sum_exec_runtime = se->sum_exec_runtime),所以sum_exec_runtime- prev_sum_exec_runtime就是這次調度佔用cpu的clock
vruntime:虛擬時間(實現CFS最關鍵的東西),簡單的理解它是執行的cpu clock的一個虛擬值,這個變換與進程的權重成反比
parent:該se的上級se(只對組調度有用)
cfs_rq:該se就緒時所屬的cfs_rq,在不同cpu上該值是不一樣的(即cfs_rq_of(se)找到的是se所在的父se的my_q)
my_q:該se下面的管理的se組成的cfs_rq(只對組調度有用),這個與cfs_rq的區別很重要,它是該se本身所管理的所有下級se所組成的運行隊列,而cfs_rq則是該se所屬的父級運行隊列

task_group#組結構體,每個group都有一個task_group結構
se:該tg在每個cpu上的se
cfs_rq:該tg在每個cpu上的cfs_rq
shares:我們用cgroup設定cpu.shares的值

對於即時調度類也是一樣的,它也是支援組調度的,它的運行隊列是使用rt_prio_array active組織的,即bitmap+lists,我們在介紹RT類的時候再詳細介紹。這些欄位的含義也是proc欄位的意思,所以理解這些對於理解proc資訊很有協助。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.