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