一、程序排程介紹:
1、程序排程的產生:
程序從使用資源方面可以分為如下兩類,不管是i/o還是cpu受限類的程序,cpu都希望再盡可能短的時間
完成更多的工作,但另一方面,又希望盡可能的減少資源(i/o或cpu)的消耗,這兩則之間存在矛盾,所以程序
的排程管理就是來協調兩者之間的衝突。
型別別稱
描述示例
i/o受限型
i/o密集型
頻繁的使用i/o裝置, 並花費很多時間等待i/o操作的完成
資料庫伺服器, 文字編輯器
cpu受限型
計算密集型
花費大量cpu時間進行數值計算
圖形繪製程式
2、程序排程器的種類:
(1)rt scheduler:實時排程器
(2)deadline scheduler:deadline排程器
(3)cfs scheduler:完全公平排程器
(4)idle scheduler:idle排程器
3、程序排程類:
(1)排程類的介紹:
系統核心排程**會通過struct sched_class
結構體的成員呼叫具體排程類的核心演算法,其結構如下:
struct sched_class
(2)具體排程類:
排程器類
描敘排程策略
stop_sched_class
優先順序最高的執行緒,會中斷所有其他執行緒,且不會被其他任務打斷
無dl_sched_class
deadline排程器
sched_deadline
rt_sched_class
實時排程器
sched_fifo、sched_rr
fair_sched_clas
完全公平排程器
sched_normal、sched_batch
idle_sched_class
idle排程器
sched_idle
排程類的優先順序為:
stop_sched_class -> dl_sched_class -> rt_sched_class -> fair_sched_class -> idle_sched_class
以完全公平排程器fair_sched_class舉例如下:
const struct sched_class fair_sched_class =
4、排程實體:
struct task_struct
struct sched_entity ;
5、權重計算:
其中靜態優先順序和nice之間的關係如下:
#define max_rt_prio 100
static_prio=max_rt_prio+nice+20
cfs排程器針對優先順序提出了nice值的概念,其實和權重是一一對應的關係。nice的取值範圍為:[-20,19],
數值越小代表優先順序越大,同時也意味著權重值越大,nice值和權重之間可以互相轉換:
static const int prio_to_weight[40] = ;
linux核心查詢如上prio的函式如下:
static void set_load_weight(struct task_struct *p)
load->weight = scale_load(prio_to_weight[prio]);
load->inv_weight = prio_to_wmult[prio];
}
6、虛擬執行時間vruntime:
cfs排程器的目標是保證每乙個程序的完全公平排程。cfs引入了虛擬時間的概念,cfs保證每個程序執行的
虛擬時間是相等的即可保證公平排程。
將實際時間轉換為vruntime的函式為:calc_delta_fair
static inline u64 calc_delta_fair(u64 delta, struct sched_entity *se)
/*
* delta_exec * weight / lw.weight
* or
* (delta_exec * (weight * lw->inv_weight)) >> wmult_shift
* * either weight := nice_0_load and lw \e prio_to_wmult, in which case
* we're guaranteed shift stays positive because inv_weight is guaranteed to
* fit 32 bits, and nice_0_load gives another 10 bits; therefore shift >= 22.
* * or, weight =< lw.weight (because lw.weight is the runqueue weight), thus
* weight/lw.weight <= 1, and therefore our shift will also be positive.
*/static u64 __calc_delta(u64 delta_exec, unsigned long weight, struct load_weight *lw)
} /* hint to use a 32x32->64 mul */
fact = (u64)(u32)fact * lw->inv_weight;
while (fact >> 32)
return mul_u64_u32_shr(delta_exec, fact, shift);
}
7、就緒佇列(runqueue):
系統中每個cpu都會有乙個全域性的就緒佇列(cpu runqueue),使用struct rq
結構體描述,每乙個排程類也
有屬於自己管理的就緒佇列。
struct rq
/* cfs-related fields in a runqueue */
struct cfs_rq
cfs維護了乙個按照虛擬時間排序的紅黑樹,所有可執行的排程實體按照p->se.vruntime排序插入紅黑樹,
cfs選擇紅黑樹最左邊的程序執行。隨著系統時間的推移,原來左邊執行過的程序慢慢的會移動到紅黑樹的右邊,
原來右邊的程序也會最終跑到最左邊。因此紅黑樹中的每個程序都有機會執行:
其中程序描敘符task_struct、 程序排程實體sched_entity、程序執行佇列cfs_rq、cfs管理的紅黑樹rb_node,
二、總結
1、每個cpu都有乙個通用就緒佇列struct rq;
2、每個程序task_struct都包含乙個排程實體struct sched_entity se結構體;
3、每個通用就緒佇列資料結構中包含有cfs rq、rt rq、dl rq(cfs_rq = &rq->cfs);
4、每個排程實體se包含乙個權重struct load_weight load結構體;
5、每個排程實體se有乙個vruntime成員表示該排程實體的虛擬時間;
6、每個排程實體se有乙個on_rq表示該排程實體是否在就緒佇列中接受排程;
7、每個cfs就緒佇列中內嵌乙個權重struct load_weight load結構體;
8、每個cfs就緒佇列中有乙個min_vruntime來跟蹤該佇列紅黑樹中最小的vruntime;
9、task_struct資料結構中,on_cpu表示程序是否正在執行狀態中;on_rq表示程序的排程狀態;
排程實體se中on_rq成員表示排程實體是否在就緒佇列中接受排程。
程序排程 介紹
完全可操作的排程準則 a fully operational scheduling discipline 對作業系統中執行的程序 有時也叫工作任務 做出如下的假設 每乙個程序執行相同的時間。所有的程序同時到達。一旦開始,每個程序保持執行直到完成。所有的程序只是用 cpu 即它們不執行 io 操作 每...
程序排程(三)
一 睡眠和喚醒 休眠 被阻塞 的程序處於乙個特殊的不可執行狀態。無論什麼原因,導致程序進入休眠狀態,核心的操作都是相同的 程序把自己標誌成休眠狀態,從可執行紅黑樹中移出,放入等待佇列,然後呼叫schedule 選擇和執行乙個其他程序。喚醒的過程正好相反,程序把自己標誌成可執行狀態,然後再從等待佇列中...
程序排程(三)
一 睡眠和喚醒 休眠 被阻塞 的程序處於乙個特殊的不可執行狀態。無論什麼原因,導致程序進入休眠狀態,核心的操作都是相同的 程序把自己標誌成休眠狀態,從可執行紅黑樹中移出,放入等待佇列,然後呼叫schedule 選擇和執行乙個其他程序。喚醒的過程正好相反,程序把自己標誌成可執行狀態,然後再從等待佇列中...