主要參考:Linux manual page - sched
概述
自從linux內(nèi)核2.6.23以來,默認(rèn)的進(jìn)程調(diào)度器就被設(shè)置為完全公平調(diào)度器(CFS,complete fair scheduler),取代了之前的O(1)調(diào)度器。
每個(gè)線程都有一個(gè)靜態(tài)調(diào)度優(yōu)先級(jí),即sched_priority字段。
一個(gè)線程的調(diào)度策略決定了線程會(huì)被插入到同級(jí)靜態(tài)優(yōu)先級(jí)的線程隊(duì)列的位置,以及它在隊(duì)列中會(huì)怎樣移動(dòng)。
所有的調(diào)度都是可插入的,如果一個(gè)更高靜態(tài)優(yōu)先級(jí)的線程準(zhǔn)備好了,現(xiàn)在運(yùn)行中的線程就會(huì)被插入。而調(diào)度策略則僅僅影響了同樣靜態(tài)優(yōu)先級(jí)的線程。
設(shè)置方法
進(jìn)程(線程)可以通過系統(tǒng)調(diào)用設(shè)置自身或者其他進(jìn)程(線程)的調(diào)度策略。
- 設(shè)置調(diào)度策略和參數(shù):
#include <sched.h>
int sched_setattr(pid_t pid, struct sched_attr *attr,
unsigned int flags);
int sched_getattr(pid_t pid, struct sched_attr *attr,
unsigned int size, unsigned int flags);
其中pid為0時(shí),設(shè)置自身的調(diào)度策略和參數(shù)。結(jié)構(gòu)體sched_attr包含以下字段:size、sched_policy(即調(diào)度策略,具體會(huì)在下一節(jié)介紹)、sched_flags、sched_nice、sched_runtime、sched_deadline、sched_period(最后三個(gè)為SCHED_DEADLINE相關(guān)的參數(shù))。當(dāng)設(shè)置成功,系統(tǒng)調(diào)用返回0;否則返回-1,并會(huì)設(shè)置errno。
- 設(shè)置CPU親和性
int sched_setaffinity(pid_t pid, size_t cpusetsize,
cpu_set_t mask);
int sched_getaffinity(pid_t pid, size_t cpusetsize,
cpu_set_t mask);
調(diào)度策略
普通進(jìn)程:SCHED_OTHER/SCHED_BATCH/SCHED_IDLE
實(shí)時(shí)進(jìn)程:SCHED_FIFO/SCHED_RR
特殊實(shí)時(shí)進(jìn)程:SCHED_DEADLINE
靜態(tài)優(yōu)先級(jí):Static_priority:對(duì)于普通進(jìn)程,靜態(tài)優(yōu)先級(jí)為0;對(duì)于實(shí)時(shí)進(jìn)程,靜態(tài)優(yōu)先級(jí)為1-99,99為最高優(yōu)先級(jí)。
動(dòng)態(tài)優(yōu)先級(jí):Dynamic_priority:僅對(duì)普通進(jìn)程有用,取決于nice和一個(gè)動(dòng)態(tài)調(diào)整的量(比如進(jìn)程ready卻沒被調(diào)度,則增加)。
- SCHED_FIFO:
FIFO指的是First In First Out。選擇SCHED_FIFO策略的進(jìn)程不會(huì)分時(shí)間片,一旦開始調(diào)度,就調(diào)度至結(jié)束,除非被其他更高優(yōu)先級(jí)進(jìn)程插入。一次調(diào)度完成后,回到該優(yōu)先級(jí)隊(duì)列的末尾。如果當(dāng)前被調(diào)度的進(jìn)程優(yōu)先級(jí)低于新增的FIFO進(jìn)程,該FIFO進(jìn)程會(huì)插入。 - SCHED_RR:
RR是Round Robin的縮寫。該調(diào)度策略是對(duì)FIFO的優(yōu)化,F(xiàn)IFO調(diào)度方式容易導(dǎo)致進(jìn)程長(zhǎng)時(shí)間占據(jù)CPU而阻塞了其他同樣重要的進(jìn)程的調(diào)度。在RR調(diào)度策略下,每個(gè)進(jìn)程的每次調(diào)度到某一時(shí)間長(zhǎng)度后,便回到該優(yōu)先級(jí)的調(diào)度隊(duì)列的最后。 - SCHED_DEADLINE:
這種調(diào)度策略有幾個(gè)主要指標(biāo):Start_Time,Arrival_Time,Relative_Deadline,Period,Absolute_Deadline,Computation_Time
有三個(gè)主要參數(shù):RunTime,Period,RelativeDeadline(均為時(shí)間長(zhǎng)度),其中RunTime是用戶預(yù)估的進(jìn)程每次執(zhí)行所需要的CPU時(shí)間,常常被設(shè)置為平均執(zhí)行時(shí)間,對(duì)于一些重要進(jìn)程,也可能被設(shè)置為最長(zhǎng)執(zhí)行時(shí)間。Period是執(zhí)行周期,每個(gè)周期內(nèi),進(jìn)程會(huì)且只會(huì)被調(diào)度一次。RelativeDeadline則是從進(jìn)程準(zhǔn)備好的時(shí)刻算起,必須被處理完的Deadline。
以SCHED_DEADLINE策略進(jìn)行調(diào)度的進(jìn)程不存在優(yōu)先級(jí),調(diào)度時(shí)不會(huì)被中斷,確定執(zhí)行。
之前一直有一個(gè)疑問:內(nèi)核如何保證實(shí)時(shí)進(jìn)程的實(shí)時(shí)性?比如如果我們?cè)O(shè)置了不合理的實(shí)時(shí)進(jìn)程分配,內(nèi)核是否還能保證實(shí)時(shí)性?實(shí)際上,以SCHED_DEADLINE調(diào)度為例,在設(shè)置的時(shí)候,會(huì)有可行性檢查,如果Kernal認(rèn)為不可行,會(huì)拒絕。 - SCHED_OTHER:
即SCHED_NORMAL,優(yōu)先級(jí)為零,按照CFS規(guī)則進(jìn)行調(diào)度。
其他
- 可以通過nice調(diào)整進(jìn)程/線程的niceness,并進(jìn)而影響普通進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí)。niceness是Per Thread的。
- cgroups只能影響非實(shí)時(shí)進(jìn)程。