循环时间共享调度算法——每个进程轮流使用CPU一段时间,
这段时间成为时间片or量子,进程无法直接控制何时使用CPU和使用CPU的时间
满足多任务系统两个需求:
1、公平性: 每个进程都有机会使用到CPU
2、响应度: 一个进程使用CPU前无需等待太长时间
每个进程都有一个nice值,范围为-20~19。数值越小优先级越高,默认为0
进程的调度不是按优先级大小进行排序调度的。
nice值越高(优先级越小)只会导致该进程占用CPU的时间变少。
#include
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相匹配
Linux有99个实时优先级,范围为1(最低)~99(最高)
POSIX API提供的实时只是软实时,根本无法达到真正的实时,只是允许控制调度哪个进程占用CPU
优先级相同的进程循环时间分享方式运行。发生进程调度的条件:
1、进程时间片耗尽
2、进程主动放弃CPU
3、进程被终止
4、被更高优先级进程抢占
与SCHED_OTHER(标准循环调度算法)不同之处:
存在严格优先级高低级别,高优先级进程总是优先级比低优先级进程执行。
SCHED_OTHER策略下搞优先级不会独占CPU,nice值只是为进程占用CPU时间提供较大权重
与SCHED_RR不同之处:
SCHED_FIFO不存在时间片
SCHED_FIFO调度策略的进程获得CPU控制权,当发生下列条件才会失去CPU控制权:
1、主动放弃CPU
2、被终止
3、被更高优先级进程抢占
非标准调度策略,虽然通过POSIX实时调度API设置,但实际上不属于实时策略。
SCHED_BATCH —— 导致频繁被唤醒的任务被调度的次数减少。
SCHED_IDLE —— 进程的nice值毫无意义,用于运行低优先级任务,
没有其他任务需要使用CPU运行才得以大量使用CPU。
#include
int sched_get_priority_min(int policy);//获得policy指定调度策略的最低优先级
int sched_get_priority_max(int policy);///获得policy指定调度策略的最高优
RETURN VALUE
成功返回优先级,失败返回-1
#include
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
//修改进程号为pid的进程优先级为param
int sched_setparam(pid_t pid, const struct sched_param *param);
RETURN VALUE
成功返回0,失败返回-1
#include
//获取进程号为pid的进程的调度策略
int sched_getscheduler(pid_t pid);
RETURN VALUE
成功返回调度策略,失败返回-1
#include
////获取进程号为pid的进程的优先级,存放在参数param中
int sched_getparam(pid_t pid, struct sched_param *param);
RETURN VALUE
成功返回0,失败返回-1
实时进程可以通过两种方式主动放弃CPU使用权:
#include
int sched_yield(void);
RETURN VALUE
成功返回0,失败返回-1
#include
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; /* 纳秒 */
}