linux2.4到linux2.6核心調度(10)__linux

來源:互聯網
上載者:User

一個進程結束運行時,如果它的互動程度比父進程低(sleep_avg 較小),那麼核心將在 sched_exit() 中對其父進程的 sleep_avg 進行調整,調整公式如下(以 child_sleep_avg 表示子進程的 sleep_avg):
sleep_avg = sleep_avg*EXIT_WEIGHT/(EXIT_WEIGHT+1) + child_sleep_avg/(EXIT_WEIGHT+1)
其中 EXIT_WEIGHT 等於 3,所以父進程的 sleep_avg 將減少自身 sleep_avg 的 1/4,再補償子進程 sleep_avg 的 1/4,優先順序也將隨之有所下降,子進程的互動程度與父進程相差越大,則優先順序的懲罰也越明顯。利用進程平均等待時間來衡量進程的優先順序,使得宏觀上相同靜態優先順序的所有進程的等待時間和已耗用時間的比值趨向一致,反映了 Linux 要求各進程分時共用 cpu 的公平性。另一方面,sleep_avg 還是進程互動式程度的衡量標準。
7. 更精確的互動式進程優先
互動式進程優先策略的實際效果在 2.4 核心中受到廣泛批評,在 2.6 核心中,這一點得到了很大改進,總體來說,核心有四處對互動式進程的優先考慮:
1) sleep_avg
上文已經詳細分析了 sleep_avg 對進程優先順序的影響,從中可以看出,互動式進程因為休眠次數多、時間長,它們的 sleep_avg 也會相應地

更大一些,所以計算出來的優先順序也會相應高一些。
2) interactive_credit
系統引入了一個 interactive_credit 的進程屬性(見"改進後的 task_struct"),用來表徵該進程是否是互動式進程:只要

interactive_credit 超過了 CREDIT_LIMIT 的閥值(HIGH_CREDIT()返回真),該進程就被認為是互動式進程。
interactive_credit 的初始值為 0,在兩種情況下它會加 1,這兩種場合都在 recalc_task_prio() 函數中:
使用者進程(p->mm!=NULL),如果不是從 TASK_UNINTERRUPTIBLE 休眠中被喚醒的(p->activated!=-1),且等待的時間(包括在休眠中

等待和在就緒隊列中等待,)超過了一定限度(sleep_time>INTERACTIVE_SLEEP(p)); 
除以上情況外,sleep_avg 經過 sleep_time 調整後,如果大於 NS_MAX_SLEEP_AVG。 
無論哪種情況,一旦 interactive_credit 超過(大於)CREDIT_LIMIT 了,它都不再增加,因此 interactive_credit 最大值就是

CREDIT_LIMIT+1。
interactive_credit 的遞減發生在 schedule() 函數中。當調度器用已耗用時間修正被切換下來的進程的 sleep_avg 之後,如果 sleep_avg 小

於等於 0,且interactive_credit 在 -CREDIT_LIMIT 和 CREDIT_LIMIT 之間(-100<=interactive_credit<=100),則 interactive_credit

減 1。可見interactive_credit 最小值為 -101,且一旦它達到 CREDIT_LIMIT+1 的最大值就不會再被減下來--它將保持在 CREDIT_LIMIT+1

的高值上。
這就是說,只有進程多次休眠,且休眠的時間足夠長(長於啟動並執行時間,長於"互動式休眠"時間),進程才有可能被列為互動式進程;而一旦

被認為是互動式進程,則永遠按互動式進程對待。
採用 HIGH_CREDIT() 標準斷言的互動式進程主要在以下兩處得到優先順序計算上的獎勵:
當進程從 cpu 上調度下來的時侯,如果是互動式進程,則它參與優先順序計算的已耗用時間會比實際已耗用時間小,以此獲得較高的優先順序

(見"進程平均等待時間 sleep_avg"); 
互動式進程處於 TASK_UNINTERRUPTIBLE 狀態下的休眠時間也會疊加到 sleep_avg 上,從而獲得優先順序獎勵(見"進程平均等待時間

sleep_avg"); 
3) TASK_INTERACTIVE()
核心另有一處不採用 HIGH_CREDIT() 這種累積方式來判斷的互動式進程優先機制,那裡使用的是 TASK_INTERACTIVE() 宏(布爾值):

prio <= static_prio-DELTA(p)

當進程時間片耗盡時,如果該宏返回真(同時 expired 隊列沒有等待過長的時間,見"新的資料結構 runqueue""expired_timestamp"條),則

該進程不進入 expired 隊列而是保留在 active 隊列中,以便儘快調度到這一互動式進程。動態優先順序在調度到該進程時在 effective_prio

() 中算出:prio=static_prio-bonus(sleep_avg)(bonus(sleep_avg) 表示 bonus 是關於 sleep_avg 的函數,見"優先順序計算過程"),而

DELTA(p) 與進程的 nice 值有關,可表示為delta(nice)。bonus 與 sleep_avg 的關係在"優先順序計算過程"一節中已經用圖說明了,delta 和

nice 之間的關係見下圖:



nice 值的範圍是 -20~19,DELTA(p)將其轉換到 -5~+5 再加上一個INTERACTIVE_DELTA常量的範圍內:TASK_NICE(p) * MAX_BONUS/40 +

INTERACTIVE_DELTA,其中 INTERACTIVE_DELTA 等於 2。
經過轉換,TASK_INTERACTIVE(p) 變為 "delta(nice) 是否不大於 bonus(sleep_avg)"。將 sleep_avg 表示為 JIFFIES 的形式,並代入常數

,delta(nice)<=bonus(sleep_avg) 可以表示為:
nice/4+2 <= bonus,-5<=bonus<=+5

從中可以看出,nice 大於 12 時,此不等式恒假,也就是說此時進程永遠不會被當作互動式進程看待;而進程靜態優先順序越高,要被當作互動

式進程所需要的 sleep_avg 上限也越低,即靜態優先順序高的進程獲得這種獎勵的機會更大。
4) 就緒等待時間的獎勵 
因為經常處於 TASK_INTERRUPTIBLE 狀態的進程最有可能是互動,因此,這一類進程從休眠中醒來後在就緒隊列上等待調度的時間長短也

將影響進程的動態優先順序。


這一工作在調度器(schedule())選擇上這一類型的進程之後進行,並且考慮到互動式進程通常都是在中斷中被喚醒的,所以核心還記錄了這

一資訊,對不由中斷喚醒的進程實行獎勵約束(詳見"進程平均等待時間sleep_avg")。

8. 調度器
有了以上的準備工作之後,現在我們可以看看調度器的主流程了。
和 2.4 的調度器相比,2.6 的 schedule()函數要更加簡單一些,減少了鎖操作,優先順序計算也拿到調度器外進行了。為減少進程在 cpu 間跳

躍,2.4 中將被切換下來的進程重新調度到另一個 cpu 上的動作也省略了。調度器的基本流程仍然可以概括為相同的五步:
清理當前運行中的進程(prev) 
選擇下一個投入啟動並執行進程(next) 
設定新進程的運行環境 
執行進程環境切換 
後期整理 
2.6 的調度器工作流程保留了很多 2.4 系統中的動作,進程切換的細節也與 2.4 基本相同(由 context_switch() 開始)。為了不與 2.4 系

統的調度器分析重複,我們按照調度器對各個資料結構的影響來分析調度器的工作流程,重點在與 2.4 調度器不同的部分,與之相同或相似的

部分相信讀者結合代碼和上文的技術分析很容易理解。同時,2.6 的調度器中還增加了對Server Load Balancer和核心搶佔啟動並執行支援,因為內容比較獨立

,我們也將其放在單獨的章節中。
1) 相關鎖
主要是因為就緒隊列分布到各個 cpu 上了,2.6 調度器中僅涉及兩個鎖的操作:就緒隊列鎖 runqueue::lock,全域核心鎖 kernel_flag。對

就緒隊列鎖的操作保證了就緒隊列的操作唯一性,核心鎖的意義與 2.4 中相同:調度器在執行切換之前應將核心鎖解開

(release_kernel_lock()),完成調度後恢複鎖狀態(reacquire_kernel_lock())。進程的鎖狀態依然儲存在task_struct::lock_depth屬性

中。
因為調度器中沒有任何全域的鎖操作,2.6 調度器本身的運行障礙幾乎不存在了。
2) prev
調度器主要影響 prev 進程的兩個屬性:
sleep_avg 減去了本進程的已耗用時間(詳見"進程平均等待時間 sleep_avg"的"被切換下來的進程"); 
timestamp 更新為目前時間,記錄被切換下去的時間,用於計算進程等待時間。 
prev被切換下來後,即使修改了 sleep_avg,它在就緒隊列中的位置也不會改變,它將一直以此優先順序參加調度直至發生狀態改變(比如休眠

)。
3) next
在前面介紹 runqueue 資料結構的時候,我們已經分析了 active/expired 兩個按優先順序排序的就緒進程隊列的功能,2.6 的調度器對候選進

程的定位有三種可能:
active 就緒隊列中優先順序最高且等待時間最久的進程;

聯繫我們

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