linux 的排程策略與優先順序
阿新 • • 發佈:2020-12-10
技術標籤:初學linuxlinux排程策略與優先順序程序/執行緒排程機制
linux 的排程策略與優先順序
參考資料如下:
- man手冊
man 7 sched
- 核心文件 Documentation/scheduler。
首先需要說明,我們常說的程序排程器是傳統的說法,但是實際上程序是資源管理的單位,執行緒才是排程的單位.有時也會說任務排程等。
linux的排程機制由排程策略(policies)
和優先順序(priority)
兩個屬性共同決定.其中排程策略又可以分為實時排程策略
和通用排程策略(非實時)
。其中通用排程策略的優先順序值為0.而實時排程策略的優先順序取值範圍為1~99.可以看出,實時排程策略的優先順序總是大於通用排程策略。而優先順序
實時排程策略
包含SCHED_RR
,SCHED_FIFO
排程策略。通用排程策略
包含SCHED_OTHER
、SCHED_IDLE
、SCHED_BATCH
排程策略。即如下關係:linux的排程機制由
排程策略(policies)
和優先順序(priority)
共同決定:
優先順序
:確定哪個執行緒被優先排程。實時排程策略的優先順序總是大於通用排程策略。排程策略(policies)
分如下幾種:實時排程策略
:spriority
值的取值範圍為0~99.當執行緒間的優先順序不同時,按照優先順序高的先排程原則。當優先順序相同時,分為如下兩種方式:SCHED_RR
:優先順序相同的執行緒按固定的時間片
SCHED_FIFO
:與SCHED_RR
相似,優先順序相同的執行緒也是迴圈排程。不過沒有時間片的概念。下面會詳細講解。
通用排程策略(非實時)
:spriority
值為0.SCHED_OTHER
:SCHED_IDLE
:SCHED_BATCH
:
所有的排程策略最後通過連結串列的方式組合成一個排程類
。由linux核心排程。
各種排程策略介紹
- 實時排程策略之
SCHED_RR
:Round-robin scheduling- 當執行緒間的優先順序不同時,優先順序高的先排程。當優先順序相同時,固定的
時間片
迴圈排程。被呼叫的執行緒滿足如下條件時會讓出CPU:- 排程期間的
時間片
使用完了。 - 自動放棄CPU。如呼叫了阻塞相關的介面函式或呼叫了sched_yield()。
- 被一個優先順序更高的執行緒搶佔了
- 執行緒終止了。
- 排程期間的
- 如果因為時間片使用完了或自願放棄CPU而導致執行緒讓出CPU,此時此執行緒將會被放置在與其優 先級級別對應的佇列的隊尾。如果因為被搶佔而讓出CPU,則會放置到隊頭,等更高優先順序讓出cpu時,繼續執行此執行緒。
- 當執行緒間的優先順序不同時,優先順序高的先排程。當優先順序相同時,固定的
- 實時排程策略之
SCHED_FIFO
:First in-first out scheduling- 與
SCHED_RR
實時排程策略相似,不過它沒有時間片
的概念。被呼叫的執行緒讓出CPU條件與SCHED_RR
類似,只是沒有時間片
使用完的情況.
- 與
- 通用排程策略之
SCHED_OTHER
:time-sharing scheduling- 分時迴圈排程策略。也就是我們常說的CFS(Completely Fair Scheduler)完全公平排程器。是系統的預設排程策略。按
動態時間片
迴圈排程。動態時間片
由nice
屬性值決定。每個SCHED_OTHER
策略的執行緒都擁有一個nice值,其取值範圍為−20~19,預設值為0.nice值是一個權重因子,值越小,權重越大。CPU為其分配的動態時間片會越多。
- 分時迴圈排程策略。也就是我們常說的CFS(Completely Fair Scheduler)完全公平排程器。是系統的預設排程策略。按
- 通用排程策略之
SCHED_BATCH
- 此策略會讓頻繁被喚醒的執行緒在排程時次數會變少。其他與SCHED_OTHER策略類似。
- 通用排程策略之
SCHED_IDLE
- 可以理解為nice=19的
SCHED_OTHER
策略。當系統中沒有其他執行緒需要使用CPU時才會大量使用CPU。
- 可以理解為nice=19的
- 排程策略之
SCHED_DEADLINE
- 自從3.14版本以來,Linux提供了一個截止日期排程策略(SCHED_DEADLINE)。
排程相關的使用者空間介面
修改nice值相關的函式介面:
int nice(int inc)
- 所屬標頭檔案:
<unistd.h>
- 描述:修改當前程序的nice值。此函式已經被更通用的setpriority()取代。
- inc:在當前nice的基礎上加inc.
- return: 如果成功,返回新設定的nice值。
- eg:nice(3)、nice(-5)
- 所屬標頭檔案:
int setpriority(int which, int who, int prio)
- 描述: 設定通用程序的nice值。這裡的priority不要與上邊講到的優先順序混淆。
- which:決定who傳入的引數含義,which可選值:
- PRIO_PROCESS:表明
who
為程序id.如果等於零,則為當前程序 - PRIO_PGRP:表明
who
為程序組id.如果等於零,則為當前程序組 - PRIO_USER:表明
who
為使用者(real user)id.如果等於零,則為當前使用者
- PRIO_PROCESS:表明
- prio:-20~19之間的nice值。
- return: 成功返回0。失敗返回-1.。
int getpriority(int which, int who)
- 所屬標頭檔案:
<sys/time.h>
,<sys/resource.h>
- 描述:獲取程序的nice值。
- return: 返回程序排程優先順序(-20~19)。
- eg: getpriority(PRIO_PROCESS, getpid());
- 所屬標頭檔案:
修改優先順序與排程策略相關的函式介面:
int sched_get_priority_max(int policy)
- 描述: 檢視排程策略最大優先順序。
- policy 可指定的值如下:
- SCHED_OTHER
- SCHED_BATCH
- SCHED_IDLE
- SCHED_FIFO
- SCHED_RR
- return: 成功返回最大優先順序值。失敗返回-1.
int sched_get_priority_min(int policy)
- 檢視排程策略最小優先順序。其他同sched_get_priority_max().
int sched_setscheduler(pid_t pid, int policy,const struct sched_param *param)
- 描述: 設定程序的排程策略和優先順序。
- policy 可指定的值如下:
- SCHED_OTHER
- SCHED_BATCH
- SCHED_IDLE 對於這三種策略,param->sched_priority的值必須為0.
- SCHED_FIFO
- SCHED_RR 對於這兩種策略,需要指定param->sched_priority的值。
- param:指定排程策略的優先順序。struct sched_param的結構體如下:
struct sched_param { int sched_priority; //優先順序1~99 };
- return: 成功返回0。失敗返回-1.
int sched_getscheduler(pid_t pid)
- 所屬標頭檔案:
<sched.h>
- 描述: 獲取程序的排程策略。
- pid 程序id.如果為0,表示為本執行緒。
- return: 成功返回排程策略值(非負整數)。失敗返回-1.
- SCHED_OTHER 0
- SCHED_FIFO 1
- SCHED_RR 2
- SCHED_BATCH 3
- SCHED_IDLE 5
- 所屬標頭檔案:
int sched_setparam(pid_t pid, const struct sched_param *param)
- 描述: 設定程序的優先順序。sched_setscheduler()函式的子集。
- param:見sched_setscheduler()函式中的描述。
- return: 成功返回0。失敗返回-1.
int sched_getparam(pid_t pid, struct sched_param *param)
- 描述: 獲取程序的優先順序。
- param:見sched_setscheduler()函式中的描述。用於接收要獲取的優先順序值。
- return: 成功返回0。失敗返回-1.
linux特有的函式介面,可用於修改上邊提到的所有屬性:
int sched_setattr(pid_t pid, struct sched_attr *attr,unsigned int flags)
- 描述: 設定程序的排程策略。
- struct sched_attr結構體如下:
struct sched_attr { u32 size; //結構體大小 u32 sched_policy; //排程策略 u64 sched_flags; //可選屬性:SCHED_FLAG_RESET_ON_FORK 表示子程序建立時不繼承此策略。 s32 sched_nice; //通用排程策略的nice值 u32 sched_priority; //優先順序 /* Remaining fields are for SCHED_DEADLINE */ u64 sched_runtime; u64 sched_deadline; u64 sched_period; };
- flags 目前為0.
- return: 成功返回0。
int sched_getattr(pid_t pid, struct sched_attr *attr,unsigned int size, unsigned int flags)
- 描述: 獲取程序的排程策略。
- size: attr結構體的大小。
- 其他引數同sched_setattr().
其他介面:
int sched_yield(void)
- 描述:程序主動放棄cpu.
int sched_rr_get_interval(pid_t pid, struct timespec *tp)
- 獲取
SCHED_RR
排程策略的程序在每次使用CPU時分配到時間片的長度。 - tp:獲取到的時間長度。
- 成功返回0,失敗返回-1.
- 獲取
執行緒相關的排程設定函式:相關執行緒屬性設定。
關於技術交流
此處後的文字已經和題目內容無關,可以不看。
qq群:825695030
微信公眾號:嵌入式的日常
如果上面的文章對你有用,歡迎打賞、點贊、評論。