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;  /* 納秒 */
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章