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; /* 納秒 */
}