Linux調(diào)度器
Linux內(nèi)核調(diào)度器是負(fù)責(zé)決定哪個(gè)進(jìn)程在何時(shí)執(zhí)行的組件。它管理著CPU資源的分配和任務(wù)的調(diào)度,以確保系統(tǒng)資源的合理利用和任務(wù)的高效執(zhí)行。Linux內(nèi)核中常見的調(diào)度器有多種,包括經(jīng)典的O(1)調(diào)度器、CFS(Completely Fair Scheduler)調(diào)度器等。這些調(diào)度器根據(jù)不同的策略和算法來(lái)進(jìn)行任務(wù)切換,如時(shí)間片輪轉(zhuǎn)、優(yōu)先級(jí)搶占等,以滿足不同場(chǎng)景下的性能要求和公平性需求。通過(guò)合理配置和選擇適當(dāng)?shù)恼{(diào)度策略,可以提高系統(tǒng)吞吐量、響應(yīng)時(shí)間,并實(shí)現(xiàn)更好地負(fù)載均衡和公平競(jìng)爭(zhēng)。
調(diào)度:Linux內(nèi)核調(diào)度器中的調(diào)度是指決定哪個(gè)進(jìn)程將獲得CPU時(shí)間片來(lái)執(zhí)行任務(wù)。調(diào)度器根據(jù)一定的策略和算法,從就緒隊(duì)列中選擇一個(gè)最合適的進(jìn)程,使其在給定的時(shí)間間隔內(nèi)運(yùn)行。這個(gè)過(guò)程稱為上下文切換,其中保存當(dāng)前進(jìn)程的上下文信息,并加載即將執(zhí)行的進(jìn)程的上下文信息。不同調(diào)度器使用不同的算法和策略來(lái)確定進(jìn)程執(zhí)行順序,如時(shí)間片輪轉(zhuǎn)、優(yōu)先級(jí)搶占等。目標(biāo)是提高系統(tǒng)整體性能、資源利用率和用戶體驗(yàn),同時(shí)保證公平性和響應(yīng)性。
Linux內(nèi)核調(diào)度器的主要作用是合理地分配CPU時(shí)間片給就緒狀態(tài)的進(jìn)程,以實(shí)現(xiàn)以下幾個(gè)目標(biāo):
-
公平性:調(diào)度器通過(guò)公平地分配CPU時(shí)間片給就緒進(jìn)程,確保每個(gè)進(jìn)程都有機(jī)會(huì)執(zhí)行,避免某個(gè)進(jìn)程長(zhǎng)期占用CPU而導(dǎo)致其他進(jìn)程無(wú)法獲得執(zhí)行機(jī)會(huì)。
-
高性能:調(diào)度器根據(jù)不同的調(diào)度策略(如CFS、Real-Time等)和優(yōu)先級(jí),動(dòng)態(tài)地選擇最適合的進(jìn)程來(lái)運(yùn)行,以提高系統(tǒng)整體的性能和吞吐量。
-
響應(yīng)性:調(diào)度器及時(shí)響應(yīng)用戶或系統(tǒng)事件,盡可能減少任務(wù)切換的延遲,提供良好的交互性能和實(shí)時(shí)響應(yīng)。
-
資源利用率:調(diào)度器根據(jù)不同的負(fù)載情況和系統(tǒng)資源狀況,動(dòng)態(tài)地分配CPU時(shí)間片給不同的進(jìn)程,最大限度地利用CPU資源并避免資源浪費(fèi)。
-
能耗管理:一些先進(jìn)的調(diào)度算法還可以考慮節(jié)能策略,在需要時(shí)降低CPU頻率或?qū)⑵渲糜谛菝郀顟B(tài),以降低功耗和延長(zhǎng)電池壽命。
kernel/sched/sched.h
kernel/sched/sched.h
是 Linux 內(nèi)核中的一個(gè)頭文件,它定義了與調(diào)度器相關(guān)的數(shù)據(jù)結(jié)構(gòu)、函數(shù)和宏。該文件是內(nèi)核調(diào)度子系統(tǒng)的一部分,其中包含了調(diào)度器實(shí)現(xiàn)的相關(guān)信息。
具體來(lái)說(shuō),sched.h
文件中定義了以下內(nèi)容:
-
調(diào)度策略和優(yōu)先級(jí):定義了不同的調(diào)度策略(如CFS、實(shí)時(shí)調(diào)度等)以及進(jìn)程的優(yōu)先級(jí)相關(guān)信息。
-
調(diào)度器數(shù)據(jù)結(jié)構(gòu):包括用于表示進(jìn)程控制塊(task_struct)、運(yùn)行隊(duì)列(runqueue)等數(shù)據(jù)結(jié)構(gòu)。
-
調(diào)度算法和函數(shù):包括實(shí)現(xiàn)不同調(diào)度策略所使用的具體算法和相關(guān)函數(shù),如CFS調(diào)度算法、優(yōu)先級(jí)計(jì)算函數(shù)等。
-
宏定義和輔助函數(shù):提供了一些輔助性宏和函數(shù),用于在調(diào)度過(guò)程中進(jìn)行狀態(tài)轉(zhuǎn)換、時(shí)間計(jì)算等操作。
可以在內(nèi)核源代碼中使用其中定義的數(shù)據(jù)類型、函數(shù)和宏來(lái)實(shí)現(xiàn)對(duì)進(jìn)程調(diào)度的操作和管理。
struct sched_class
是 Linux 內(nèi)核中用于描述調(diào)度器類別的結(jié)構(gòu)體。它定義了每種調(diào)度策略(如 CFS、實(shí)時(shí)調(diào)度等)的相關(guān)操作和屬性。
在內(nèi)核源碼中,struct sched_class
結(jié)構(gòu)體通常會(huì)有多個(gè)實(shí)例,每個(gè)實(shí)例對(duì)應(yīng)一個(gè)特定的調(diào)度策略。不同的調(diào)度策略有不同的名稱和實(shí)現(xiàn)方式,但它們都需要遵循 struct sched_class
結(jié)構(gòu)體所定義的接口。
struct sched_class {
// 指向下一個(gè) sched_class 結(jié)構(gòu)體的指針,用于形成鏈表結(jié)構(gòu)
const struct sched_class *next;
// 將一個(gè)進(jìn)程添加到運(yùn)行隊(duì)列中(即調(diào)度器將該進(jìn)程調(diào)度到 CPU 上執(zhí)行)
void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
// 將一個(gè)進(jìn)程從運(yùn)行隊(duì)列中移除(即調(diào)度器取消對(duì)該進(jìn)程的調(diào)度)
void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
// 檢查調(diào)度器是否應(yīng)該搶占當(dāng)前進(jìn)程
void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int flags);
// 選取下一個(gè)要運(yùn)行的進(jìn)程(即進(jìn)行進(jìn)程調(diào)度)
struct task_struct *(*pick_next_task) (struct rq *rq);
// 當(dāng)前進(jìn)程時(shí)間片結(jié)束時(shí)調(diào)用的回調(diào)函數(shù)
void (*put_prev_task) (struct rq *rq, struct task_struct *prev);
// 獲取進(jìn)程的優(yōu)先級(jí)
int (*get_priority) (struct task_struct *p);
// 設(shè)置進(jìn)程的優(yōu)先級(jí)
void (*set_curr_task_priority) (struct rq *rq, struct task_struct *p, int prio);
// 檢查進(jìn)程是否具有實(shí)時(shí)調(diào)度策略
bool (*task_has_rt_policy)(struct task_struct *p);
// 檢查進(jìn)程是否具有分時(shí)調(diào)度策略
bool (*task_has_dl_policy)(struct task_struct *p);
// 檢查進(jìn)程是否具有負(fù)載平衡調(diào)度策略
bool (*task_can_attach)(struct task_struct *p);
// 進(jìn)行運(yùn)行隊(duì)列的初始化
void (*set_cpus_allowed)(struct task_struct *p, const struct cpumask *new_mask);
// 從當(dāng)前運(yùn)行隊(duì)列中移除一個(gè)進(jìn)程
void (*rq_online)(struct rq *rq);
// 將一個(gè)進(jìn)程添加到當(dāng)前運(yùn)行隊(duì)列中
void (*rq_offline)(struct rq *rq);
// 將進(jìn)程遷移至另一個(gè) CPU 的運(yùn)行隊(duì)列中
int (*task_waking)(struct task_struct *p, unsigned int state);
// 在進(jìn)程狀態(tài)改變時(shí)調(diào)用的回調(diào)函數(shù)
void (*task_change_group)(struct task_struct *p, int type);
// 在進(jìn)程 CPU 綁定發(fā)生變化時(shí)調(diào)用的回調(diào)函數(shù)
void (*task_set_group)(struct task_struct *p);
// 獲取當(dāng)前正在運(yùn)行的進(jìn)程
struct task_struct *(*get_rr_interval)(struct rq *rq, struct task_struct *task);
};
調(diào)度類
常見的調(diào)度類:
-
實(shí)時(shí)調(diào)度類(Real-Time Scheduling Class):用于實(shí)時(shí)任務(wù),具有最高優(yōu)先級(jí),并且可以通過(guò)固定時(shí)間片或基于優(yōu)先級(jí)的搶占來(lái)進(jìn)行調(diào)度。
-
實(shí)時(shí)負(fù)載均衡調(diào)度類(Real-Time Load Balancer Scheduling Class):用于負(fù)載均衡操作,以確保系統(tǒng)中的實(shí)時(shí)任務(wù)得到合理分配和調(diào)度。
-
實(shí)時(shí)限制調(diào)度類(Real-Time Throttle Scheduling Class):用于限制實(shí)時(shí)任務(wù)的執(zhí)行資源,以避免其他重要任務(wù)被過(guò)多耗費(fèi)。
-
CFS(Completely Fair Scheduler)調(diào)度類:用于普通進(jìn)程的搶占式多任務(wù)調(diào)度。CFS通過(guò)紅黑樹來(lái)組織運(yùn)行隊(duì)列,并為每個(gè)進(jìn)程分配時(shí)間片以平等分享CPU資源。
-
Idle(空閑)調(diào)度類:用于處理空閑CPU時(shí)間,在沒有可執(zhí)行任務(wù)需要運(yùn)行時(shí)將CPU置于休眠狀態(tài),以節(jié)省能源。
-
停機(jī)調(diào)度類(Stop Scheduling Class):如前面提到的,用于處理被標(biāo)記為停機(jī)狀態(tài)的進(jìn)程,這些進(jìn)程不再參與正常的調(diào)度過(guò)程。
實(shí)時(shí)調(diào)度類
實(shí)時(shí)調(diào)度類是操作系統(tǒng)中用于處理具有嚴(yán)格時(shí)間約束的實(shí)時(shí)任務(wù)的一種調(diào)度類。在大多數(shù)現(xiàn)代操作系統(tǒng)中,通常會(huì)提供多個(gè)不同的實(shí)時(shí)調(diào)度類,以滿足不同類型和需求的實(shí)時(shí)任務(wù)。
常見的實(shí)時(shí)調(diào)度類包括:
- SCHED_FIFO:使用先進(jìn)先出(FIFO)調(diào)度策略,根據(jù)優(yōu)先級(jí)確定任務(wù)執(zhí)行順序。具有較高優(yōu)先級(jí)的任務(wù)將一直執(zhí)行,直到它們自愿放棄CPU資源。
- SCHED_RR:使用輪轉(zhuǎn)(Round-Robin)調(diào)度策略,在相同優(yōu)先級(jí)任務(wù)之間進(jìn)行時(shí)間片輪轉(zhuǎn)。每個(gè)任務(wù)都有一個(gè)固定時(shí)間片來(lái)執(zhí)行,如果時(shí)間片耗盡,則會(huì)被放回隊(duì)列等待下次輪轉(zhuǎn)。
- SCHED_DEADLINE:基于最后期限(Deadline)的調(diào)度策略,允許開發(fā)者為每個(gè)任務(wù)指定絕對(duì)截止日期,并確保在截止日期之前完成任務(wù)。這種調(diào)度類主要用于周期性實(shí)時(shí)任務(wù)。
實(shí)時(shí)負(fù)載均衡調(diào)度類
實(shí)時(shí)負(fù)載均衡調(diào)度類是一種用于在實(shí)時(shí)系統(tǒng)中分配任務(wù)和資源的調(diào)度算法。其目標(biāo)是確保實(shí)時(shí)任務(wù)在多個(gè)處理器或核心上平衡地分布,以提高系統(tǒng)的性能和可靠性。
這些調(diào)度類通??紤]以下因素:
- 實(shí)時(shí)任務(wù)的優(yōu)先級(jí):根據(jù)任務(wù)的緊急程度和重要性確定優(yōu)先級(jí)順序。
- 處理器或核心的負(fù)載狀況:監(jiān)測(cè)各個(gè)處理器或核心的負(fù)載情況,包括當(dāng)前執(zhí)行的任務(wù)數(shù)量和運(yùn)行時(shí)間等。
- 任務(wù)之間的依賴關(guān)系:考慮到實(shí)時(shí)任務(wù)之間可能存在的依賴關(guān)系,確保滿足這些依賴關(guān)系以避免延遲。
一些常見的實(shí)時(shí)負(fù)載均衡調(diào)度算法包括:
4. 最小負(fù)載優(yōu)先(Least Load First):選擇最空閑的處理器或核心來(lái)分配新任務(wù)。
5. 最短剩余時(shí)間優(yōu)先(Shortest Remaining Time Next):選擇剩余執(zhí)行時(shí)間最短的任務(wù)進(jìn)行調(diào)度,以最小化響應(yīng)時(shí)間。
6. 周期性負(fù)載均衡(Periodic Load Balancing):周期性地檢查處理器或核心之間的負(fù)載,并重新分配任務(wù)以保持平衡。
實(shí)時(shí)限制調(diào)度類
實(shí)時(shí)限制調(diào)度類是一種用于在實(shí)時(shí)系統(tǒng)中管理和控制任務(wù)執(zhí)行速率的調(diào)度算法。該調(diào)度類主要用于限制任務(wù)的執(zhí)行頻率,以確保系統(tǒng)資源的合理利用和任務(wù)的可靠性。
實(shí)時(shí)限制調(diào)度類通??紤]以下因素:
- 任務(wù)的執(zhí)行時(shí)間:監(jiān)測(cè)每個(gè)任務(wù)的執(zhí)行時(shí)間,包括開始時(shí)間和結(jié)束時(shí)間。
- 任務(wù)之間的時(shí)間間隔:確定每個(gè)任務(wù)之間需要保持的最小時(shí)間間隔。
- 系統(tǒng)負(fù)載情況:根據(jù)系統(tǒng)當(dāng)前負(fù)載情況動(dòng)態(tài)調(diào)整任務(wù)的執(zhí)行速率。
基本原理是通過(guò)控制每個(gè)任務(wù)之間的最小時(shí)間間隔或執(zhí)行次數(shù)來(lái)限制其執(zhí)行速率。這可以防止某些耗時(shí)較長(zhǎng)或資源占用較高的任務(wù)對(duì)系統(tǒng)產(chǎn)生過(guò)大影響,從而提高系統(tǒng)穩(wěn)定性和可靠性。
CFS調(diào)度類
CFS調(diào)度類是一個(gè)在Linux內(nèi)核中用于多任務(wù)調(diào)度的算法。它旨在以公平和高效的方式分配CPU時(shí)間片給各個(gè)運(yùn)行的進(jìn)程。
CFS通過(guò)使用紅黑樹數(shù)據(jù)結(jié)構(gòu)來(lái)管理進(jìn)程,并基于進(jìn)程的虛擬運(yùn)行時(shí)間(vruntime)進(jìn)行排序。每個(gè)進(jìn)程都被賦予一個(gè)虛擬運(yùn)行時(shí)間,該時(shí)間反映了該進(jìn)程應(yīng)該獲得的CPU時(shí)間片相對(duì)于其他進(jìn)程的優(yōu)先級(jí)。較短虛擬運(yùn)行時(shí)間的進(jìn)程會(huì)被放在紅黑樹的前面,有更高的優(yōu)先級(jí),可以獲得更多的CPU執(zhí)行時(shí)間。
CFS實(shí)現(xiàn)了完全公平性,即盡可能地使每個(gè)任務(wù)能夠以相等或接近相等的比例共享CPU資源。這意味著沒有任務(wù)會(huì)因?yàn)槠渌蝿?wù)長(zhǎng)期占用CPU而被餓死(starvation)。CFS會(huì)動(dòng)態(tài)地計(jì)算每個(gè)進(jìn)程應(yīng)獲得的虛擬運(yùn)行時(shí)間,并將其作為參考來(lái)確定下一個(gè)要運(yùn)行的進(jìn)程。
Idle調(diào)度類
當(dāng)CPU上沒有任何活動(dòng)進(jìn)程需要運(yùn)行時(shí),操作系統(tǒng)會(huì)將CPU分配給Idle調(diào)度類來(lái)處理。Idle調(diào)度類不涉及實(shí)際的任務(wù)調(diào)度或時(shí)間片分配,而是讓CPU處于空閑狀態(tài)以降低功耗和熱量產(chǎn)生。
當(dāng)沒有活動(dòng)進(jìn)程需要運(yùn)行時(shí),內(nèi)核會(huì)讓CPU進(jìn)入Idle狀態(tài),并等待下一個(gè)事件發(fā)生。這個(gè)事件可以是外部中斷、硬件觸發(fā)或其他需要處理的事件。一旦有新的活動(dòng)任務(wù)到達(dá)或者有其他需要處理的事件發(fā)生,內(nèi)核就會(huì)切換到適當(dāng)?shù)恼{(diào)度類來(lái)管理CPU資源。
Idle調(diào)度類通常被認(rèn)為是“什么都不做”的調(diào)度類別,在確保系統(tǒng)資源利用率和效能的同時(shí)節(jié)省了功耗。
停機(jī)調(diào)度類
用于處理處于停機(jī)狀態(tài)的進(jìn)程。當(dāng)一個(gè)進(jìn)程暫時(shí)不需要運(yùn)行時(shí),它可以被切換到停機(jī)調(diào)度類來(lái)節(jié)省CPU資源。
停機(jī)調(diào)度類是Completely Fair Scheduler(CFS)的一部分。當(dāng)一個(gè)進(jìn)程被切換到停機(jī)調(diào)度類后,它將不會(huì)被調(diào)度執(zhí)行,直到滿足某些條件使其重新激活。
常見的觸發(fā)條件包括等待某個(gè)事件的發(fā)生、等待輸入/輸出操作完成或等待其他進(jìn)程的信號(hào)。當(dāng)這些條件滿足時(shí),進(jìn)程將從停機(jī)狀態(tài)恢復(fù)并轉(zhuǎn)移到適當(dāng)?shù)恼{(diào)度類以進(jìn)行執(zhí)行。
通過(guò)將閑置或暫時(shí)不需要執(zhí)行任務(wù)的進(jìn)程切換到停機(jī)調(diào)度類,系統(tǒng)可以有效地管理CPU資源,并避免浪費(fèi)計(jì)算能力。
優(yōu)先級(jí)
Linux 內(nèi)核中的優(yōu)先級(jí)通常是指進(jìn)程(或線程)的調(diào)度優(yōu)先級(jí),也稱為 Nice 值。在 Linux 中,Nice 值的范圍是 -20
到 19
,其中 -20
表示最高優(yōu)先級(jí),而 19
表示最低優(yōu)先級(jí)。
Nice 值越小,進(jìn)程的調(diào)度優(yōu)先級(jí)越高,越容易獲得 CPU 時(shí)間片。例如,Nice 值為 -20
的進(jìn)程會(huì)比 Nice 值為 19
的進(jìn)程更容易獲得 CPU 時(shí)間片。內(nèi)核使用 Nice 值來(lái)決定哪個(gè)進(jìn)程應(yīng)該運(yùn)行,以及每個(gè)進(jìn)程應(yīng)該獲得多長(zhǎng)時(shí)間的 CPU 時(shí)間片。
除了 Nice 值之外,Linux 還支持實(shí)時(shí)調(diào)度類和普通調(diào)度類等不同類型的調(diào)度策略。實(shí)時(shí)調(diào)度類通常用于需要快速響應(yīng)的任務(wù),如音頻處理、運(yùn)動(dòng)控制等領(lǐng)域;而普通調(diào)度類則用于普通的計(jì)算任務(wù),如文本處理、編譯等。
task_struct結(jié)構(gòu)體
task_struct
是 Linux 內(nèi)核中用于表示進(jìn)程或線程的數(shù)據(jù)結(jié)構(gòu),含了許多字段來(lái)存儲(chǔ)與進(jìn)程相關(guān)的信息,例如進(jìn)程狀態(tài)、調(diào)度信息、內(nèi)存管理、文件描述符等。
在 task_struct
結(jié)構(gòu)體中,通常有三個(gè)成員變量用于表示進(jìn)程的優(yōu)先級(jí)。它們分別是:
-
prio
:表示進(jìn)程的靜態(tài)優(yōu)先級(jí),即進(jìn)程在創(chuàng)建時(shí)分配給它的優(yōu)先級(jí)。在 Linux 中,進(jìn)程的靜態(tài)優(yōu)先級(jí)的范圍是100
(最高優(yōu)先級(jí))到139
(最低優(yōu)先級(jí))。 -
rt_priority
:表示實(shí)時(shí)優(yōu)先級(jí)。對(duì)于實(shí)時(shí)進(jìn)程,它的優(yōu)先級(jí)可以高于普通進(jìn)程的prio
值。實(shí)時(shí)優(yōu)先級(jí)的范圍是0
(最高優(yōu)先級(jí))到99
(最低優(yōu)先級(jí))。 -
normal_prio
:表示動(dòng)態(tài)優(yōu)先級(jí),也稱為當(dāng)前優(yōu)先級(jí)。動(dòng)態(tài)優(yōu)先級(jí)是根據(jù)進(jìn)程的歷史行為和負(fù)載情況等動(dòng)態(tài)調(diào)整的優(yōu)先級(jí)。動(dòng)態(tài)優(yōu)先級(jí)的范圍是100
(最高優(yōu)先級(jí))到139
(最低優(yōu)先級(jí))。
在 Linux 中,進(jìn)程的調(diào)度策略可以是 SCHED_NORMAL
、SCHED_FIFO
或 SCHED_RR
等。對(duì)于 SCHED_NORMAL
調(diào)度策略的進(jìn)程,動(dòng)態(tài)優(yōu)先級(jí)等于靜態(tài)優(yōu)先級(jí);對(duì)于 SCHED_FIFO
和 SCHED_RR
調(diào)度策略的實(shí)時(shí)進(jìn)程,動(dòng)態(tài)優(yōu)先級(jí)等于實(shí)時(shí)優(yōu)先級(jí)。
抱歉,我之前給出的路徑不正確。在 Linux 內(nèi)核中,進(jìn)程的優(yōu)先級(jí)定義可以在以下路徑下找到:include/linux/sched/prio.h
。
在該頭文件中,定義了進(jìn)程的靜態(tài)優(yōu)先級(jí)的范圍、實(shí)時(shí)優(yōu)先級(jí)的范圍以及其他與優(yōu)先級(jí)相關(guān)的常量和宏。
#define MAX_USER_RT_PRIO 100
#define MAX_RT_PRIO MAX_USER_RT_PRIO
#define MAX_PRIO (MAX_RT_PRIO + NICE_WIDTH)
#define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2)
-
MAX_USER_RT_PRIO
定義了實(shí)時(shí)優(yōu)先級(jí)中用戶可用的最大優(yōu)先級(jí),其值為 100。 -
MAX_RT_PRIO
定義了實(shí)時(shí)優(yōu)先級(jí)中的最大優(yōu)先級(jí),其值等于MAX_USER_RT_PRIO
。 -
NICE_WIDTH
是一個(gè)宏定義,在 Linux 內(nèi)核中表示可調(diào)整的優(yōu)先級(jí)范圍。在這里沒有給出具體定義,但通常是一個(gè)較小的正整數(shù)。 -
MAX_PRIO
定義了進(jìn)程可以具有的最大優(yōu)先級(jí)。它由MAX_RT_PRIO
和NICE_WIDTH
相加得到。 -
DEFAULT_PRIO
定義了默認(rèn)進(jìn)程優(yōu)先級(jí)。它通過(guò)將MAX_RT_PRIO
和NICE_WIDTH / 2
相加得到。
這些常量用于確定進(jìn)程或線程在調(diào)度器中的相對(duì)優(yōu)先級(jí)。實(shí)時(shí)優(yōu)先級(jí)(Real-Time Priority)用于處理時(shí)間關(guān)鍵任務(wù),而普通進(jìn)程則根據(jù)靜態(tài)優(yōu)先級(jí)和動(dòng)態(tài)調(diào)整因子(如 NICE 值)來(lái)進(jìn)行調(diào)度。
調(diào)度策略
調(diào)度策略是操作系統(tǒng)用來(lái)決定哪個(gè)進(jìn)程或線程應(yīng)該在給定時(shí)間片內(nèi)運(yùn)行的算法。不同的調(diào)度策略可以根據(jù)不同的需求和目標(biāo)進(jìn)行選擇。
以下是一些常見的調(diào)度策略:
-
SCHED_OTHER(CFS調(diào)度器):標(biāo)準(zhǔn)的時(shí)間片輪轉(zhuǎn)調(diào)度算法。
-
SCHED_FIFO(實(shí)時(shí)先進(jìn)先出):按照優(yōu)先級(jí)進(jìn)行調(diào)度,直到任務(wù)完成或者被更高優(yōu)先級(jí)任務(wù)搶占。
-
SCHED_RR(實(shí)時(shí)輪轉(zhuǎn)):按照優(yōu)先級(jí)進(jìn)行調(diào)度,每個(gè)任務(wù)都有一個(gè)固定的時(shí)間片來(lái)執(zhí)行,超過(guò)時(shí)間片后被放到隊(duì)列尾部繼續(xù)等待。
-
SCHED_BATCH(批處理):為了提高系統(tǒng)整體性能而設(shè)計(jì)的調(diào)度策略,在CPU空閑時(shí)運(yùn)行批處理任務(wù)。
-
SCHED_IDLE(空閑):只有當(dāng)沒有其他可運(yùn)行任務(wù)時(shí)才會(huì)運(yùn)行該任務(wù)。
這些常量可以通過(guò)使用sched_setscheduler()
和sched_getscheduler()
等系統(tǒng)調(diào)用函數(shù)來(lái)設(shè)置和獲取進(jìn)程或線程的調(diào)度策略。
多處理器系統(tǒng)
Linux內(nèi)核中有幾種常見的多處理器調(diào)度策略:
-
對(duì)稱多處理(SMP)調(diào)度:在對(duì)稱多處理系統(tǒng)中,每個(gè)處理器核心都可以獨(dú)立地運(yùn)行任務(wù)。Linux使用完全公平調(diào)度(CFS)算法來(lái)均衡負(fù)載并按照優(yōu)先級(jí)進(jìn)行任務(wù)分配。
-
實(shí)時(shí)多處理(RT-MP)調(diào)度:實(shí)時(shí)多處理調(diào)度針對(duì)具有嚴(yán)格時(shí)間限制和實(shí)時(shí)需求的應(yīng)用程序。它提供了精確的響應(yīng)時(shí)間保證,并通過(guò)確定性調(diào)度算法將任務(wù)分配給不同的處理器核心。
-
CPU集群調(diào)度:CPU集群指的是一組緊密連接的處理器核心,可以共享緩存和其他資源。Linux通過(guò)自適應(yīng)層次調(diào)度算法將任務(wù)動(dòng)態(tài)地分配到合適的CPU集群中,以最大程度地利用共享資源。
CFS 調(diào)度器
CFS是Linux內(nèi)核中默認(rèn)的進(jìn)程調(diào)度器,引入于Linux 2.6.23版本。CFS調(diào)度器旨在提供公平、高效和可擴(kuò)展的進(jìn)程調(diào)度。
CFS調(diào)度器使用紅黑樹數(shù)據(jù)結(jié)構(gòu)來(lái)維護(hù)任務(wù)隊(duì)列,并通過(guò)動(dòng)態(tài)地分配時(shí)間片給每個(gè)任務(wù)來(lái)實(shí)現(xiàn)公平性。它以時(shí)間片(稱為虛擬運(yùn)行時(shí)間)的方式對(duì)任務(wù)進(jìn)行量化,較長(zhǎng)時(shí)間未被執(zhí)行的任務(wù)將獲得更多的虛擬運(yùn)行時(shí)間。
在Linux內(nèi)核中,根據(jù)任務(wù)的權(quán)重值(也稱為nice值)和調(diào)度策略,可以計(jì)算出任務(wù)的運(yùn)行時(shí)間。
在CFS(Completely Fair Scheduler)調(diào)度器中,任務(wù)的權(quán)重值由其nice值決定,通過(guò)對(duì)比不同任務(wù)的權(quán)重值,CFS會(huì)分配合理的CPU時(shí)間片給每個(gè)任務(wù)。其中較高權(quán)重(較低nice值)的任務(wù)將獲得更多的CPU時(shí)間片用于執(zhí)行。
在每個(gè)sched_latency
周期內(nèi),CFS會(huì)動(dòng)態(tài)地根據(jù)任務(wù)的權(quán)重來(lái)計(jì)算各個(gè)任務(wù)應(yīng)該獲得的運(yùn)行時(shí)間。這種計(jì)算方式被稱為"虛擬運(yùn)行時(shí)間"(virtual runtime),它反映了每個(gè)任務(wù)相對(duì)于其他任務(wù)應(yīng)該占有CPU資源的比例。
通過(guò)不斷更新和調(diào)整虛擬運(yùn)行時(shí)間,CFS能夠?qū)崿F(xiàn)公平而均衡的任務(wù)調(diào)度,并盡量保證所有進(jìn)程都能獲得合理的CPU執(zhí)行時(shí)間。這種機(jī)制使得低優(yōu)先級(jí)或高負(fù)載情況下的進(jìn)程仍然能夠被適當(dāng)?shù)貓?zhí)行,并防止某些進(jìn)程長(zhǎng)期霸占CPU資源。
是的,Linux 內(nèi)核通過(guò)抽象出調(diào)度類 struct sched_class
來(lái)封裝具有共性特征的調(diào)度算法,并在實(shí)例化各個(gè)調(diào)度器時(shí)根據(jù)具體的調(diào)度算法來(lái)實(shí)現(xiàn)。
struct sched_class
定義了一組函數(shù)指針,這些函數(shù)指針對(duì)應(yīng)了調(diào)度算法中的各個(gè)操作。通過(guò)這些函數(shù)指針,可以實(shí)現(xiàn)對(duì)進(jìn)程的調(diào)度、掛起、恢復(fù)等操作。
在 Linux 內(nèi)核中,每個(gè)調(diào)度器都會(huì)定義自己的 struct sched_class
實(shí)例,并根據(jù)具體的調(diào)度算法來(lái)實(shí)現(xiàn)這些函數(shù)指針。CFS(完全公平調(diào)度器)就定義了自己的 struct sched_class
實(shí)例,并實(shí)現(xiàn)了對(duì)應(yīng)的函數(shù)指針,來(lái)實(shí)現(xiàn)公平調(diào)度算法。
當(dāng)內(nèi)核需要進(jìn)行進(jìn)程調(diào)度時(shí),會(huì)根據(jù)進(jìn)程的調(diào)度策略選擇相應(yīng)的調(diào)度器,并調(diào)用該調(diào)度器的 struct sched_class
實(shí)例中相應(yīng)的函數(shù)指針進(jìn)行操作。
在調(diào)度核心代碼 kernel/sched/core.c
中,通過(guò) task->sched_class->xxx_func
的方式來(lái)執(zhí)行具體的調(diào)度函數(shù),這可以看作是一種類似于 C++ 中的多態(tài)機(jī)制。
在 Linux 內(nèi)核中,struct task_struct
是描述進(jìn)程或線程的數(shù)據(jù)結(jié)構(gòu),它包含了許多與進(jìn)程相關(guān)的信息,其中之一就是調(diào)度器的指針 sched_class
。
當(dāng)需要對(duì)任務(wù)進(jìn)行調(diào)度時(shí),內(nèi)核會(huì)根據(jù)任務(wù)的調(diào)度器指針 sched_class
來(lái)查找對(duì)應(yīng)的調(diào)度類,并使用其中的函數(shù)指針來(lái)完成具體的調(diào)度操作。這種方式實(shí)現(xiàn)了一種類似于多態(tài)的效果,即不同的任務(wù)可以使用不同的調(diào)度算法,而調(diào)度器的函數(shù)指針則根據(jù)具體的調(diào)度器類型來(lái)指向?qū)?yīng)的函數(shù)。
通過(guò)這種方式,Linux 內(nèi)核可以根據(jù)任務(wù)的調(diào)度器類型來(lái)調(diào)用相應(yīng)的調(diào)度函數(shù),實(shí)現(xiàn)了靈活的調(diào)度策略,并且能夠方便地?cái)U(kuò)展和切換不同的調(diào)度器。這種設(shè)計(jì)使得內(nèi)核的調(diào)度器模塊具有良好的可擴(kuò)展性和可維護(hù)性。
rq/cfs_rq/task_struct/task_group/sched_entity 結(jié)構(gòu)體
-
task_struct
:是Linux內(nèi)核中表示進(jìn)程或線程的數(shù)據(jù)結(jié)構(gòu)。它包含了進(jìn)程的各種屬性和狀態(tài)信息,如進(jìn)程ID、調(diào)度策略、優(yōu)先級(jí)等。 -
rq
:運(yùn)行隊(duì)列(runqueue)是一個(gè)用于存儲(chǔ)可運(yùn)行進(jìn)程的隊(duì)列。每個(gè)CPU核心都有一個(gè)運(yùn)行隊(duì)列,其中包含了在該核心上等待執(zhí)行的任務(wù)。 -
task_group
:任務(wù)組是一組相關(guān)聯(lián)的進(jìn)程,通常由一個(gè)父進(jìn)程和其所有子進(jìn)程組成。它們共享資源限制和調(diào)度策略,并通過(guò)signal_struct
來(lái)進(jìn)行統(tǒng)一管理。 -
sched_entity
:調(diào)度實(shí)體是用于跟蹤和管理每個(gè)進(jìn)程/線程在調(diào)度器中的狀態(tài)和屬性的數(shù)據(jù)結(jié)構(gòu)。它包含了諸如運(yùn)行時(shí)間、虛擬運(yùn)行時(shí)間、權(quán)重值等信息,并與其他數(shù)據(jù)結(jié)構(gòu)相互關(guān)聯(lián)以進(jìn)行調(diào)度決策。 -
cfs_rq
:CFS(Completely Fair Scheduler)隊(duì)列是用于實(shí)現(xiàn)公平調(diào)度的數(shù)據(jù)結(jié)構(gòu)。每個(gè)CPU核心都有一個(gè)CFS隊(duì)列,負(fù)責(zé)管理可運(yùn)行的進(jìn)程集合。
struct task_struct
結(jié)構(gòu)體
struct task_struct {
volatile long state; // 進(jìn)程狀態(tài)(運(yùn)行、等待等)
void *stack; // 進(jìn)程堆棧指針
atomic_t usage; // 引用計(jì)數(shù)
unsigned int flags; // 進(jìn)程標(biāo)志位
unsigned int ptrace; // ptrace標(biāo)志
struct llist_node wake_entry; // 等待隊(duì)列節(jié)點(diǎn)
int on_cpu; // 當(dāng)前運(yùn)行進(jìn)程所在的 CPU 編號(hào)
int on_rq; // 是否在運(yùn)行隊(duì)列上
int prio; // 動(dòng)態(tài)優(yōu)先級(jí),用于調(diào)度算法
int static_prio; // 靜態(tài)優(yōu)先級(jí),用于調(diào)度算法的基準(zhǔn)值
int normal_prio; // 平均動(dòng)態(tài)優(yōu)先級(jí),考慮了任務(wù)執(zhí)行歷史和時(shí)間片輪轉(zhuǎn)
unsigned int rt_priority; // 實(shí)時(shí)進(jìn)程優(yōu)先級(jí)
#ifdef CONFIG_SCHED_DEBUG
unsigned long sleep_avg;
unsigned long long timestamp, last_ran;
#endif
struct sched_class *sched_class;
struct sched_entity se;
struct sched_rt_entity rt;
#ifndef CONFIG_PREEMPT_NOTIFIERS
// ...
#endif
// ...
};
struct task_group
結(jié)構(gòu)體
struct task_group {
/* 該組的父組 */
struct task_group *parent;
/* 與該組關(guān)聯(lián)的 cgroup */
struct cgroup_subsys_state css;
#ifdef CONFIG_CGROUP_CPUACCT
/*
* cpuacct 和 cpu 變量需要在同一個(gè)緩存行上,因?yàn)樗鼈冊(cè)陬l繁訪問和更新時(shí)使用。
*
* 不要將這兩個(gè)變量分開,否則可能會(huì)導(dǎo)致不同 CPU 上的偽共享。
*/
struct task_group_cpuacct cpuacct;
#endif
#ifdef CONFIG_CGROUP_CPUSET
// ...
#endif
#ifdef CONFIG_FAIR_GROUP_SCHED
/* 調(diào)度策略相關(guān)字段 */
struct sched_entity **se; /* 指向每個(gè)調(diào)度實(shí)體結(jié)構(gòu)體(sched_entity)的指針數(shù)組 */
// ...
/* 這些字段用于統(tǒng)計(jì)信息和負(fù)載均衡操作 */
unsigned long load_last_balance; /* 上次平衡時(shí)的負(fù)載值 */
u64 load_prev_update; /* 上次更新平均負(fù)載時(shí)間戳 */
unsigned long aggregated_load_avg; /* 平均聚合負(fù)載值 */
int nr_running; /* 組內(nèi)正在運(yùn)行任務(wù)數(shù)量 */
atomic_long_t util_avg[CPU_STAT_NSTATES]; /* CPU 利用率統(tǒng)計(jì)信息 */
// ...
#endif
// ...
};
struct sched_entity
結(jié)構(gòu)體
struct sched_entity {
struct load_weight load; // 進(jìn)程的負(fù)載權(quán)重
struct rb_node run_node; // 在運(yùn)行隊(duì)列中以紅黑樹形式組織的節(jié)點(diǎn)
unsigned int on_rq; // 標(biāo)志位,指示進(jìn)程是否在運(yùn)行隊(duì)列中
u64 exec_start; // 進(jìn)程最近一次執(zhí)行開始時(shí)間戳
u64 sum_exec_runtime; // 總執(zhí)行時(shí)間(包括所有CPU核心)
u64 vruntime; // 進(jìn)程虛擬運(yùn)行時(shí)間(Fair調(diào)度算法使用)
#ifdef CONFIG_SCHED_DEBUG
u64 prev_sum_exec_runtime; // 上一個(gè)統(tǒng)計(jì)周期內(nèi)的總執(zhí)行時(shí)間
#endif
#ifndef CONFIG_64BIT
unsigned int __pad;
#endif
struct sched_statistics statistics; // 調(diào)度統(tǒng)計(jì)信息
#ifdef CONFIG_FAIR_GROUP_SCHED
struct sched_entity *parent; // 父進(jìn)程的調(diào)度實(shí)體指針(任務(wù)組)
#endif
#ifdef CONFIG_UCLAMP_TASK
struct uclamp_se clamp[UCLAMP_CNT]; // 進(jìn)程對(duì)應(yīng)每個(gè)UCLAMP檔案級(jí)別的約束值
#endif
#ifdef CONFIG_SCHED_WALT
/* ... */
#endif
};
實(shí)際運(yùn)行時(shí)間(runtime)和一個(gè)虛擬運(yùn)行時(shí)間(vruntime)
在CFS調(diào)度器中,沒有固定的時(shí)間片概念。相反,它使用了實(shí)際運(yùn)行時(shí)間和虛擬運(yùn)行時(shí)間來(lái)進(jìn)行任務(wù)排序和選擇調(diào)度。
實(shí)際運(yùn)行時(shí)間是指任務(wù)在CPU上真正執(zhí)行的時(shí)間。每當(dāng)任務(wù)被選中并分配給CPU時(shí),它會(huì)累積實(shí)際運(yùn)行時(shí)間。
虛擬運(yùn)行時(shí)間是一個(gè)相對(duì)概念,它取決于任務(wù)在CFS隊(duì)列中的位置以及其他相關(guān)因素。具體而言,虛擬運(yùn)行時(shí)間與進(jìn)程優(yōu)先級(jí)有關(guān)。高優(yōu)先級(jí)的任務(wù)會(huì)獲得更多的虛擬運(yùn)行時(shí)間,在排序和選擇調(diào)度時(shí)更容易被選中。
計(jì)算虛擬運(yùn)行時(shí)間涉及到一些復(fù)雜的算法和數(shù)據(jù)結(jié)構(gòu),主要目標(biāo)是使各個(gè)任務(wù)能夠公平地競(jìng)爭(zhēng)CPU資源。通過(guò)動(dòng)態(tài)調(diào)整虛擬運(yùn)行時(shí)間,CFS調(diào)度器可以保持系統(tǒng)的負(fù)載均衡,并提供對(duì)不同優(yōu)先級(jí)任務(wù)的適當(dāng)響應(yīng)。
每個(gè)任務(wù)都有一個(gè)實(shí)際運(yùn)行時(shí)間(runtime)和一個(gè)虛擬運(yùn)行時(shí)間(vruntime)。這兩個(gè)參數(shù)用于計(jì)算任務(wù)的優(yōu)先級(jí)和選擇下一個(gè)要執(zhí)行的任務(wù)。
-
實(shí)際運(yùn)行時(shí)間(runtime):表示任務(wù)在CPU上真正執(zhí)行的時(shí)間。每當(dāng)任務(wù)被選中并分配給CPU時(shí),它會(huì)累積實(shí)際運(yùn)行時(shí)間。通過(guò)記錄實(shí)際運(yùn)行時(shí)間,CFS可以了解每個(gè)任務(wù)在過(guò)去多長(zhǎng)時(shí)間內(nèi)使用了CPU資源。
-
虛擬運(yùn)行時(shí)間(vruntime):是一個(gè)相對(duì)概念,用于衡量任務(wù)的優(yōu)先級(jí)。較高優(yōu)先級(jí)的任務(wù)會(huì)獲得更多的虛擬運(yùn)行時(shí)間,從而在排序和選擇調(diào)度時(shí)更容易被選中。虛擬運(yùn)行時(shí)間與進(jìn)程優(yōu)先級(jí)有關(guān),并根據(jù)一定的算法進(jìn)行動(dòng)態(tài)調(diào)整。
CFS調(diào)度器使用vruntime來(lái)進(jìn)行任務(wù)排序和選擇調(diào)度。它根據(jù)每個(gè)任務(wù)的vruntime值來(lái)確定下一個(gè)要執(zhí)行的最合適的任務(wù)。通過(guò)比較不同任務(wù)之間的vruntime值,CFS可以保持系統(tǒng)負(fù)載均衡,并確保按照其優(yōu)先級(jí)公平地分配CPU資源。
CFS(完全公平調(diào)度器)的主要流程調(diào)用:
-
初始化:在系統(tǒng)啟動(dòng)時(shí),初始化 CFS 調(diào)度器相關(guān)數(shù)據(jù)結(jié)構(gòu)和參數(shù)。
-
進(jìn)程創(chuàng)建:當(dāng)一個(gè)新進(jìn)程被創(chuàng)建時(shí),為其分配調(diào)度實(shí)體
struct sched_entity
,并初始化相關(guān)屬性。 -
進(jìn)程插入調(diào)度隊(duì)列:通過(guò)調(diào)用
enqueue_task_fair()
函數(shù),將進(jìn)程插入 CFS 調(diào)度隊(duì)列中,并更新調(diào)度信息。 -
選擇下一個(gè)運(yùn)行進(jìn)程:在每個(gè)時(shí)鐘中斷時(shí),調(diào)用
pick_next_task_fair()
函數(shù)選擇下一個(gè)應(yīng)該運(yùn)行的進(jìn)程。 -
上下文切換:如果選定的進(jìn)程與當(dāng)前正在運(yùn)行的進(jìn)程不同,則進(jìn)行上下文切換,將 CPU 分配給新的進(jìn)程。
-
時(shí)間片耗盡:當(dāng)當(dāng)前運(yùn)行進(jìn)程的時(shí)間片耗盡時(shí),調(diào)用
put_prev_task_fair()
函數(shù)更新運(yùn)行進(jìn)程的虛擬運(yùn)行時(shí)間,并重新插入調(diào)度隊(duì)列。 -
進(jìn)程退出或掛起:當(dāng)一個(gè)進(jìn)程退出或被掛起時(shí),調(diào)用
dequeue_task_fair()
函數(shù)將其從調(diào)度隊(duì)列中移除。 -
時(shí)鐘中斷處理:在每個(gè)時(shí)鐘中斷處理程序中,調(diào)用
task_tick_fair()
函數(shù)更新當(dāng)前運(yùn)行進(jìn)程的虛擬運(yùn)行時(shí)間,并檢查是否需要進(jìn)行調(diào)度決策。 -
負(fù)載均衡:定期進(jìn)行負(fù)載均衡,調(diào)用相關(guān)的負(fù)載均衡函數(shù),如
load_balance()
,以確保各個(gè) CPU 上的任務(wù)分布均衡。 -
循環(huán)調(diào)度:重復(fù)執(zhí)行步驟 4-9,不斷選擇下一個(gè)運(yùn)行進(jìn)程并進(jìn)行調(diào)度,以實(shí)現(xiàn)公平的 CPU 時(shí)間片分配。
虛擬運(yùn)行時(shí)間是通過(guò)以下公式計(jì)算得出的:
虛擬運(yùn)行時(shí)間 = 實(shí)際運(yùn)行時(shí)間 * NICE_0_LOAD / 該任務(wù)的權(quán)重
時(shí)鐘中斷事件
CFS 調(diào)度器的 tick 是一個(gè)時(shí)鐘中斷事件,它用于觸發(fā)調(diào)度器進(jìn)行調(diào)度決策。在 Linux 內(nèi)核中,CFS 調(diào)度器通過(guò)時(shí)鐘中斷來(lái)進(jìn)行時(shí)間片的分配和進(jìn)程的切換。
每當(dāng)一個(gè) tick 發(fā)生時(shí),內(nèi)核會(huì)調(diào)用相關(guān)的時(shí)鐘中斷處理程序。在 CFS 調(diào)度器中,這個(gè)處理程序主要做兩件事情:
-
更新當(dāng)前運(yùn)行進(jìn)程的虛擬運(yùn)行時(shí)間:通過(guò)調(diào)用
task_tick_fair()
函數(shù),更新當(dāng)前運(yùn)行進(jìn)程的虛擬運(yùn)行時(shí)間。這個(gè)虛擬運(yùn)行時(shí)間的增加,可以理解為當(dāng)前進(jìn)程消耗了一個(gè)時(shí)間片(time slice)的時(shí)間。 -
進(jìn)行調(diào)度決策:在更新了虛擬運(yùn)行時(shí)間之后,時(shí)鐘中斷處理程序會(huì)檢查是否需要進(jìn)行調(diào)度決策。這個(gè)決策是通過(guò)調(diào)用
check_preempt_curr()
函數(shù)來(lái)完成的。該函數(shù)會(huì)比較當(dāng)前運(yùn)行進(jìn)程與其他就緒隊(duì)列中的進(jìn)程的優(yōu)先級(jí),如果有更高優(yōu)先級(jí)的進(jìn)程等待運(yùn)行,則會(huì)觸發(fā)上下文切換,將 CPU 分配給新的進(jìn)程。
通過(guò)這樣的方式,CFS 調(diào)度器能夠在每個(gè) tick 中根據(jù)進(jìn)程的虛擬運(yùn)行時(shí)間和優(yōu)先級(jí)進(jìn)行調(diào)度決策,以確保公平地分配 CPU 時(shí)間片。這種基于時(shí)鐘中斷的調(diào)度機(jī)制使得 CFS 能夠動(dòng)態(tài)地根據(jù)進(jìn)程的運(yùn)行情況進(jìn)行調(diào)度,以實(shí)現(xiàn)更好的系統(tǒng)性能和響應(yīng)性。
以下是CFS調(diào)度tick時(shí)鐘中斷事件的基本流程:
-
定時(shí)器觸發(fā):操作系統(tǒng)設(shè)置一個(gè)定時(shí)器,在每個(gè)時(shí)鐘周期結(jié)束時(shí)觸發(fā)中斷。這個(gè)定時(shí)器一般以毫秒或微秒為單位。
-
中斷處理程序執(zhí)行:當(dāng)定時(shí)器觸發(fā)時(shí),CPU會(huì)暫停當(dāng)前正在執(zhí)行的任務(wù),并跳轉(zhuǎn)到預(yù)先注冊(cè)的中斷處理程序(tick handler)。
-
更新任務(wù)信息:在tick handler中,首先需要更新運(yùn)行狀態(tài)、統(tǒng)計(jì)信息和優(yōu)先級(jí)等相關(guān)數(shù)據(jù)結(jié)構(gòu)。這些數(shù)據(jù)結(jié)構(gòu)包括進(jìn)程控制塊(PCB)、紅黑樹等。
-
進(jìn)程選?。涸贑FS調(diào)度算法中,選擇下一個(gè)最公平的進(jìn)程來(lái)運(yùn)行是關(guān)鍵步驟。該算法通過(guò)維護(hù)一棵紅黑樹來(lái)實(shí)現(xiàn)公平性。
-
進(jìn)程切換:如果需要進(jìn)行進(jìn)程切換,即切換到新選取的進(jìn)程執(zhí)行,則進(jìn)行上下文切換操作。這涉及保存當(dāng)前進(jìn)程的寄存器狀態(tài),并恢復(fù)待執(zhí)行進(jìn)程的寄存器狀態(tài)。
-
執(zhí)行新進(jìn)程:完成上下文切換后,CPU開始執(zhí)行新選取的進(jìn)程,該進(jìn)程會(huì)繼續(xù)運(yùn)行一段時(shí)間或直到下一個(gè)時(shí)鐘中斷。
-
繼續(xù)定時(shí)器:tick handler結(jié)束后,操作系統(tǒng)重新設(shè)置定時(shí)器,并恢復(fù)之前被中斷的任務(wù)。CPU繼續(xù)執(zhí)行被恢復(fù)的任務(wù),直到下一個(gè)tick事件觸發(fā)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-798753.html
參考推薦:Linux內(nèi)核源碼分析教程文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-798753.html
到了這里,關(guān)于【Linux 內(nèi)核源碼分析】進(jìn)程調(diào)度 -CFS 調(diào)度器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!