程序排程三 程序排程介紹

2021-09-07 18:13:49 字數 4070 閱讀 1238

一、程序排程介紹:

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 選擇和執行乙個其他程序。喚醒的過程正好相反,程序把自己標誌成可執行狀態,然後再從等待佇列中...