首先,從不同的角度,可以對執行中的程序分類。
如,從資源耗損的角度,可以分為i/o受限(頻繁使用i/o裝置)和cpu受限(需要大量的cpu計算)。
又如,從執行模式上,可以分為互動式程序(需要大量的時間等待使用者的鍵盤和滑鼠指令,同時程序需要在指令到達後被盡快喚醒),批處理程序(如編譯程式,資料庫等),實時程序(如軟體codec,編碼對實時性要求很高)。
還如,從在核心中被排程的方式上,可以分為fifo(實時程序),rr(時間片輪轉實時程序), normal(普通程序)
然後,再來了解一下程序在宣告週期中的狀態。
1,可執行狀態(task_runing)
程序要麼是在cpu上執行,要麼準備執行,所以實際上這個狀態包括執行中(running)和準備好了(ready)兩個狀態
2,可中斷的等待狀態(task_interruptible)
程序被掛起,直到某個條件或者時間滿足(硬體中斷/程序等待資源被釋放/傳遞給程序乙個訊號)變為task-running。
3,不可中斷的等待狀態(task-uninterruptible)
與2類似,不同的是訊號無法遷移其狀態,少用。
4,暫停狀態(task_stopped)
程序在收到sigstop,sigtstp,sigttin,sigttou訊號後,進入此狀態,執行被暫停。
5,跟蹤狀態(task_traced)
程序的執行由debugger暫停。
6,殭屍狀態(exit_zombit)
程序執行被終止,但是資源還未被父親(如果父親已經推出,則由init程序)**。
7,僵死撤銷狀態(exit_dead)
對於已經終止的程序,資源已經被父親或init**,程序已經被刪除,為防止其他執行執行緒**此程序,故設定此狀態。
具體的狀態切換見下圖:
程序排程:
1,linux的程序排程基於分時技術:多個程序以「時間多路復用」方式執行,也就是我們常說的時間片。時間片的長短採取折衷機制,即儘量減少對系統響應的影響,同時又降低程序切換的開銷。
2,程序的優先順序是動態的,儘管確實有靜態優先順序的存在。
3,linux的程序是搶占式的,如果進入task_running狀態且優先順序比當前執行的程序高,當前程序被終止,將cpu交給更高優先順序的程序。同時自己的tif_need_resched被設定,以便時鐘中斷處理程式終止時排程程式被正常呼叫。需要指出的是被搶走cpu的程序仍然是task_running狀態,知識出於ready的子狀態。
排程演算法:
乙個排程演算法機制對於計算機的執行時狀態影響是非常大的。
在早期的核心版本上,每次程序切換時,核心掃瞄可執行的task鍊錶,計算優先順序,然後選擇最佳task執行,如果處於可執行的task太多,這個演算法耗費的時間就很多,因為這個task選擇的複雜度是o(n)。
在2.6核心上,對於o(n)task選擇演算法做了重大改進,基於runqueue,每個cpu都有自己的執行佇列,這個佇列裡面有組織好的task結構,可以再常數時間o(1)內找個下乙個得到cpu執行許可權的task。
在2.6.23版本之後,o(1)被cfs(completely fire scheduler),這個排程器的複雜度為o(logn)。
在文章的最開頭,便介紹了從排程型別上講,程序可分為實時(又包括全實時和基於時間片的實時程序)和非實時程序。
linux雖然不是標準的rtos,但是也有實時性的需要(比如,個人曾經參與過乙個系統的開發,乙個arm雙核的處理器分別跑的乙個rtos t-kernel和linux,經常會出現linux資料傳送排程不上,導致rtos餓死的現象,後來改為fifo的就好多了
),因此核心對實時性程序也有支援。
1,普通程序的排程。
每個普通程序都有自己的靜態優先順序(從100最高到139最低,預設120),這是它被排程器評估是否能暫用cpu的乙個指標,但是,請注意,不是全部指標。
與這個靜態優先順序和另外乙個叫做nice(-20到19)值的玩意兒對應,可以通過修改task的nice,可以改變其優先順序,進而該錶其拿到的時間片。
程序基本時間片與優先順序的關係如下:
靜態優先順序大於等於120:時間片 = (140 - 靜態優先順序)* 5
靜態優先順序小於120: 時間片 = (140 - 靜態優先順序)* 20
從上面公式可以看到靜態優先順序越小,拿到的時間片越多。
優先順序、nice值、基本時間片和睡眠時間極限值對應關係見下表 說明
靜態優先順序
nice
基本時間片
最大睡眠時間
最高靜態優先順序
100-20
800ms
299ms
高靜態優先順序
110-10
600ms
499ms
預設靜態優先順序
1200
100ms
799ms
低靜態優先順序
13010
50ms
999ms
最低靜態優先順序
13919
5ms1199ms
這裡要插一句,為什麼時間片會影響執行呢,因為排程器將程序分為活動程序和過期程序。
為了防止低優先順序得不到cpu,在當乙個程序用完所有時間片後,他就從活動變成了過期,過期程序不參與排程,從而讓低優先順序的任務也得到排程。
上面提到了「靜態優先順序只是能否被排程上的乙個指標,而不是全部」,那剩下的是什麼呢?
normal程序除了靜態優先順序之外,還有動態優先順序,其範圍同樣是100(最高)到139(最低)。
靜態優先順序是用來基於task能獲得的時間片,而動態優先順序是值排程器在選擇程序是直接使用的依據。
在介紹動態優先順序的計算之前,先來了解乙個叫做bonus的數(年終了,看見這個單詞總是有點激動啊)
bonus是範圍從0到10的值,以5為分割線,分別表示獎勵(大於)或者懲罰(大於),這個獎勵懲罰**於該task過去的執行狀態,即其睡眠時間。
動態優先順序計算法公式:
動態優先順序 = max(100, min(靜態優先順序 - bonus + 5,139))
2,實時程序的排程
實時程序也有乙個優先順序,叫做實時優先順序(從1到99,1最高,99最低)。有更高優先順序的實時task在執行時,並且嚴格按照優先順序來執行,所以,低優先順序是無法執行的,實時程序一直是活動程序。
實時程序只有在以下三種情況讓出cpu:
a,有更好優先順序的實時程序產生或者啟用。
b,自己shced_yield讓出cpu
c,程序退出或被殺。
d,執行了阻塞操作進入睡眠等待喚醒
e,如果是帶時間片的實時,時間片用完。
ps:對於帶時間片的實時程序,即擁有實時優先順序,又擁有靜態優先順序,修改nice值只會改變其擁有的時間片大小,不修改其實時優先順序。
Linux 程序排程演算法
程序排程 無論是在批處理系統還是分時系統中,使用者程序數一般都多於處理機數 這將導致它們互相爭奪處理機。另外,系統程序也同樣需要使用處理機。這就要求程序排程程式按一定的策略,動態地把處理機分配給處於就緒佇列中的某乙個程序,以使之執行。程序排程具有四條基本屬性和三個基本狀態 基本屬性 1 多型性 從誕...
Linux 程序排程演算法
linux中的程序排程演算法分類如下 一 先來先服務和短作業 程序 優先排程演算法 1 先來先服務排程演算法 fcfs 先來先服務 first come first service fcfs 排程演算法是一種最簡單的 不可搶占式的 排程演算法,既可用於作業排程,也可用於程序排程。該演算法按照程序進入...
linux程序排程演算法
一 什麼是程序排程 都知道linux是一種多使用者多工的作業系統,而當多個程序同時執行去,搶占有限資源的時候,這時作業系統就會按照一定的原則將資源合理分配給請求資源的程序,這就是程序排程。二 在linux作業系統中都有哪些程序排程演算法 1.先進先出演算法 fifo 按照程序進入就緒佇列的先後次序來...