天天看點

Linux程序優先級和排程

Linux程序排程算法預設模型

循環時間共享排程算法——每個程序輪流使用CPU一段時間,
這段時間成為時間片or量子,程序無法直接控制何時使用CPU和使用CPU的時間
滿足多任務系統兩個需求:
1、公平性: 每個程序都有機會使用到CPU
2、響應度: 一個程序使用CPU前無需等待太長時間
           

程序優先級(nice值)

每個程序都有一個nice值,範圍為-20~19。數值越小優先級越高,預設為0
程序的排程不是按優先級大小進行排序排程的。
nice值越高(優先級越小)隻會導緻該程序占用CPU的時間變少。
           

擷取和修改程序優先級

#include <sys/resource.h>

int getpriority(int which, id_t who);

RETURN VALUE
    成功傳回程序的nice值,失敗傳回-1
    
int setpriority(int which, id_t who, int prio);

RETURN VALUE 
    成功傳回0, 失敗傳回-1
    
//which —— 修改優先級操作選項 : 
    //PRIO_PROCESS 操作程序ID為who的程序;若who為0,表示該函數程序的ID
    //PRIO_PGRP 操作程序組ID為who的程序組所有成員;若為who為0,表示使用調用該函數程序的程序組的ID
    //PRIO_USER 操作所有真實使用者ID為who的程序。若who為0,使用調用者真實使用者ID
    
//prio —— 程序優先級(nice值)
    //nice值設定超過範圍,會直接将nice設定為邊界值
           
特權級程序能修改任意程序的優先級。

非特權程序可以修改自己的優先級以及其他程序優先級,前提是:
	該程序真實或有效使用者ID必須與修改它的程序的有效使用者ID相比對
           

實時程序調用

  • 實時應用必須要為外部輸入提供擔保最大相應時間
  • 高優先級程序應該能夠互斥通路CPU直到程序結束或主動釋放CPU
  • 實時應用應該能夠緊缺控制其元件程序的排程順序
Linux有99個實時優先級,範圍為1(最低)~99(最高)
           
POSIX API提供的實時隻是軟實時,根本無法達到真正的實時,隻是允許控制排程哪個程序占用CPU
           

實時程序排程政策

SCHED_RR政策

優先級相同的程序循環時間分享方式運作。發生程序排程的條件:
	1、程序時間片耗盡
	2、程序主動放棄CPU
	3、程序被終止
	4、被更高優先級程序搶占
與SCHED_OTHER(标準循環排程算法)不同之處:
	存在嚴格優先級高低級别,高優先級程序總是優先級比低優先級程序執行。
	SCHED_OTHER政策下搞優先級不會獨占CPU,nice值隻是為程序占用CPU時間提供較大權重
           

SCHED_FIFO政策

與SCHED_RR不同之處:
	SCHED_FIFO不存在時間片
SCHED_FIFO排程政策的程序獲得CPU控制權,當發生下列條件才會失去CPU控制權:
	1、主動放棄CPU
	2、被終止
	3、被更高優先級程序搶占
           

SCHED_BATCH和SCHED_IDLE政策

非标準排程政策,雖然通過POSIX實時排程API設定,但實際上不屬于實時政策。
SCHED_BATCH —— 導緻頻繁被喚醒的任務被排程的次數減少。
SCHED_IDLE —— 程序的nice值毫無意義,用于運作低優先級任務,
			  沒有其他任務需要使用CPU運作才得以大量使用CPU。
           

實時優先級範圍

#include <sched.h>

int sched_get_priority_min(int policy);//獲得policy指定排程政策的最低優先級
int sched_get_priority_max(int policy);///獲得policy指定排程政策的最高優

RETURN VALUE
    成功傳回優先級,失敗傳回-1
           

擷取和修改排程政策和優先級

修改排程政策和優先級

#include <sched.h>

int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
//pid —— 程序ID
//policy —— 排程政策
//param —— 要設定的優先級
RETURN VALUE
    成功傳回0,失敗傳回-1
           

struct sched_param:

struct sched_param{
    int sched_priority;  /* 排程優先級 */
}
           

policy的取值:

實時排程政策 說明
SCHED_FIFO 實時先進先出
SCHED_RR 實時循環
非實時排程政策 說明
SCHED_OTHER 标準循環時間分享
SCHED_BATCH 與SCHED_OTHER類似,用于批量執行
SCHED_IDLE 與SCHED_OTHER類似,但優先級比最大的nice值(即最低優先級還要低)

僅設定優先級

#include <sched.h>

//修改程序号為pid的程序優先級為param
int sched_setparam(pid_t pid, const struct sched_param *param); 

RETURN VALUE 
	成功傳回0,失敗傳回-1
           

擷取排程政策和優先級

#include <sched.h>

//擷取程序号為pid的程序的排程政策
int sched_getscheduler(pid_t pid); 

RETURN VALUE 
	成功傳回排程政策,失敗傳回-1
           
#include <sched.h>

擷取程序号為pid的程序的優先級,存放在參數param中
int sched_getparam(pid_t pid, struct sched_param *param); 

RETURN VALUE
	成功傳回0,失敗傳回-1
           

釋放CPU

實時程序可以通過兩種方式主動放棄CPU使用權:

  • 調用阻塞的系統調用
  • 調用sched_yield()
#include <sched.h>

int sched_yield(void);

RETURN VALUE 
    成功傳回0,失敗傳回-1
           

擷取SCHED_RR時間片

#include <sched.h>

int sched_rr_get_interval(pid_t pid, struct timespec *tp);

RETURN VALUE
    成功傳回0,失敗傳回-1
           

struct timespec:

struct timespec{
    time_t tv_sec; /* 秒 */
    logn tv_nsec;  /* 納秒 */
}
           

繼續閱讀