1 convential process
1.1 static priority
範圍爲100-139(MAX_RT_PRIO - MAX_PRIO-1)
內核2.6中的靜態優先級相當於內核2.4中的nice值,但轉到MAX_RT_PRIO到MAX_PRIO-1取值範圍,其公式爲:
static priority = nice + 20 + MAX_RT_PRIO
內核定義兩個宏來實現此轉化:nice_to_prio() and prio_to_nice()
#define NICE_TO_PRIO(nice) (MAX_RT_PRIO + (nice) + 20) #define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20)
在進程task_struct中用int static_prio表示。
一個進程繼承其父進程的靜態優先級。也可以通過nice() or setpriority()指定。決定了Base Time Quantum大小。
static priority | Base Time Quantum |
---|---|
< 120 | (140 - static priority) × 20 |
>= 120 | (140 - static priority) × 5 |
1.2 dynamic priority
範圍與靜態優先級相同。
動態優先級是調度器選擇一個進程時實際參考的值。
dynamic priority = max( 100, min((static priority - bonus + 5), 139))
即動態優先級與靜態優先級和bonus值有關,而bonus取值範圍爲0-10,其值大小與平均睡眠時間(average sleeping time)有關。
平均睡眠時間越大,bonus值越大,其動態優先級越大。(睡眠時間長了自然要提高其動態優先級以避免發生飢餓現象)
在task_struct中用int prio來表示。
動態優先級的計算過程在各個進程的運行過程中進行,同時影響動態優先級大小的因素集中反映在sleep_avg上。
task_struct中的成員 unsigned long sleep_avg;
進程創建時,在wake_up_forked_process()中子進程繼承了父進程的動態優先級,並添加到父進程的就緒隊列中,如果父進程不在任何就緒隊列中,則通過effective_prio()來計算出子進程的動態優先級並根據計算結果將子進程放置到相應的就緒隊列中。
動態優先級的計算只要由effective_prio()函數來完成:
static int effective_prio(task_t *p) { int bonus, prio; if (rt_task(p)) ;;如果是實時進程則返回(實時進程的動態優先級是由setscheduler()函數設置且一經設置不再改變) return p->prio; bonus = CURRENT_BONUS(p) - MAX_BONUS / 2; ;;根據睡眠時間設置bonus值 prio = p->static_prio - bonus; ;;由靜態優先級和bonus值來設置動態優先級 if (prio < MAX_RT_PRIO) ;;動態優先級範圍不能小於MAX_RT_PRIO也不能超過MAX_PRIO,所以此處做下判斷。 prio = MAX_RT_PRIO; if (prio > MAX_PRIO-1) prio = MAX_PRIO-1; return prio; }
#define CURRENT_BONUS(p) \ (NS_TO_JIFFIES((p)->sleep_avg) * MAX_BONUS / \ ;;把睡眠時間轉化爲bonus值 MAX_SLEEP_AVG)
最大bonus值的計算如下:
#define USER_PRIO(p) ((p)-MAX_RT_PRIO) #define MAX_USER_PRIO (USER_PRIO(MAX_PRIO)) ;;40 #define PRIO_BONUS_RATIO 25 #define MAX_BONUS (MAX_USER_PRIO * PRIO_BONUS_RATIO / 100) ;;結果爲10
最大平均睡眠時間計算如下:
#define DEF_TIMESLICE (100 * HZ / 1000) #define MAX_SLEEP_AVG (DEF_TIMESLICE * MAX_BONUS)
2 real-time process
2.1 static priority
與非實時進程相同。
2.2 dynamic priority
其值是在setscheduler()中設置的且一經設置便不再改變。
非實時進程的動態優先級會在進程運行過程中動態計算而實時進程的動態優先級不會改變。
2.3 real time priority
每個實時進程都有一與其相關的實時優先級,取值範圍0-MAX_RT_PRIO-1。
其大小可以通過sched_setscheduler()和sched_setparam()來改變。
實時進程被一個進程替換,可能的情況有:
- 進程被擁有更高優先級的進程搶佔。
- 進程發生阻塞進入睡眠狀態。
- 進程被終止(狀態爲TASK_STOPPED OR TASK_TRACED)或者被殺死(EXIT_DEAD OR EXIT_ZOMBIE)。
- 進程通過調用sched_yield()自願放棄處理器。
- 進程是輪迴實時(SCHED_RR)且其時間片執行完畢。
當在SCHED_RR時調用nice()和set_priority()函數並不影響實時優先級,只會影響靜態優先級(從而影響基時間片)。
3 調度策略
task_struct中unsigned long policy;指定調度策略,其值可以取:
#define SCHED_NORMAL 0 //非實時進程,基於優先級的輪迴法(Round Robin) #define SCHED_FIFO 1 //實時進程,先進先出
#define SCHED_RR 2 //實時進程,基於優先級的輪迴法(Round Robin)