背景知识
linux内核目前实现了6中调度策略(即调度算法), 用于对不同类型的进程进行调度, 或者支持某些特殊的功能,其中SCHED_NORMAL和SCHED_BATCH调度普通的非实时进程, SCHED_FIFO和SCHED_RR和SCHED_DEADLINE则采用不同的调度策略调度实时进程, SCHED_IDLE则在系统空闲时调用idle进程.
字段 | 描述 | 所在调度器类 |
---|---|---|
SCHED_NORMAL | (也叫SCHED_OTHER)用于普通进程,通过CFS调度器实现。SCHED_BATCH用于非交互的处理器消耗型进程。SCHED_IDLE是在系统负载很低时使用 | CFS |
SCHED_BATCH | SCHED_NORMAL普通进程策略的分化版本。采用分时策略,根据动态优先级(可用nice()API设置),分配CPU运算资源。注意:这类进程比上述两类实时进程优先级低,换言之,在有实时进程存在时,实时进程优先调度。但针对吞吐量优化, 除了不能抢占外与常规任务一样,允许任务运行更长时间,更好地使用高速缓存,适合于成批处理的工作 | CFS |
SCHED_IDLE | 优先级最低,在系统空闲时才跑这类进程(如利用闲散计算机资源跑地外文明搜索,蛋白质结构分析等任务,是此调度策略的适用者) | CFS-IDLE |
SCHED_FIFO | 先入先出调度算法(实时调度策略),相同优先级的任务先到先服务,高优先级的任务可以抢占低优先级的任务 | RT |
SCHED_RR | 轮流调度算法(实时调度策略),后者提供 Roound-Robin 语义,采用时间片,相同优先级的任务当用完时间片会被放到队列尾部,以保证公平性,同样,高优先级的任务可以抢占低优先级的任务。不同要求的实时任务可以根据需要用sched_setscheduler() API设置策略 | RT |
SCHED_DEADLINE | 新支持的实时进程调度策略,针对突发型计算,且对延迟和完成时间高度敏感的任务适用。基于Earliest Deadline First (EDF) 调度算法 | DL |
linux优先级
#define MAX_NICE 19
#define MIN_NICE -20
#define NICE_WIDTH (MAX_NICE - MIN_NICE + 1)
#define MAX_USER_RT_PRIO 100
#define MAX_RT_PRIO MAX_USER_RT_PRIO
#define MAX_PRIO (MAX_RT_PRIO + NICE_WIDTH)
#define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2)
程序的优先级范围为[0,139],有效的实时优先级(RT priority)范围为[0,99],SCHED_NORMAL和SCHED_BATCH这两个非实时任务的优先级为[100,139]。[100,139]这个区间的优先级又称为静态优先级(static priority)。之所以称为静态优先级是因为它不会随着时间而改变,内核不会修改它,只能通过系统调用nice去修改。静态优先级用进程描述符中的static_prio表示。优先级的值越低,表示具有更高的优先级,0的优先级最高。
优先级范围 | 描述 |
---|---|
0——99 | 实时进程(RT priority)优先级范围 |
100——139 | 非实时进程(非实时调度器SCHED_NORMAL和SCHED_BATCH)优先级范围 |
用户的nice值[-20,19]对应于静态优先级的[100,139],也就是说,nice值越小,优先级越低。用户的nice值与优先级的转化关系为
#define NICE_TO_PRIO(nice) ((nice) + DEFAULT_PRIO)
#define PRIO_TO_NICE(prio) ((prio) - DEFAULT_PRIO)
其中DEFAULT_PRIO的值为120,对应的nice值为0
一个进程可以间接地通过使用进程的nice级别来改变静态优先级。一个具有更高级别的静态优先级进程会具有更长的时间片(进程在一个处理器上运行多长时间)。也就说,在用户空间通过nice命令设置进程的静态优先级, 这在内部会调用nice系统调用, 进程的nice值在-20~+19之间. 值越低优先级越高。setpriority系统调用也可以用来设置进程的优先级。它不仅能够修改单个线程的优先级, 还能修改进程组中所有进程的优先级, 或者通过制定UID来修改特定用户的所有进程的优先级
图1- 优先级
nice time为cpu处理nice过的进程所耗费的时间
top中的PR和NI
top中的PR表示优先级,但是跟上述的值不是直接对等的。在top中,实时优先级的[0,99]没有具体的表示,统一用RT来表示。而静态优先级和top中的优先级关系为
top_PR = static_Priority - 100
也就是说,top中的PR取值为[0,39],对应图1的优先级[100,139]
top中的NI表示nice等级,nice的取值为[-20,19],对应图1中的优先级为[100,139],也就是说nice等级可以改变用户进程(非实时进程的优先级)。在top界面中,输入r即可启动nice系统,先输入进程id,回车后再输入nice等级即可修改
修改了nice等级的top进程
ps中的PRI
这里的PRI与图1 中的优先级关系为
ps_PRI = static_priority - 40
这边PRI的取值范围为[-40,99],也就是说,ps中PRI值为80等价于nice值为0,等价于静态优先级的120。
ps中部分FLAGS
<,高优先级( 其他用户不能nice)
N,低优先级(其他用户可以nice)
renice命令
renice的使用方法为
Usage:
renice [-n] <priority> [-p] <pid> [<pid> ...]
renice [-n] <priority> -g <pgrp> [<pgrp> ...]
renice [-n] <priority> -u <user> [<user> ...]
Options:
-g, --pgrp <id> interpret as process group ID
-h, --help print help
-n, --priority <num> set the nice increment value
-p, --pid <id> force to be interpreted as process ID
-u, --user <name|id> interpret as username or user ID
-v, --version print version
For more information see renice(1).
例如将pid=27343的进程renice为1
renice 1 27343
其中<priority>取值为[-20,19],如果值小于-20,自动取-20,如果值大于19,自动取19
参考
https://blog.csdn.net/gatieme/article/details/51719208
https://blog.csdn.net/yiyeguzhou100/article/details/50994232
https://www.zhihu.com/question/272086181/answer/368848493
相关源码(Ubuntu 14.04)
/usr/src/linux-headers-4.4.0-31/include/linux/sched/prio.h
#ifndef _SCHED_PRIO_H
#define _SCHED_PRIO_H
#define MAX_NICE 19
#define MIN_NICE -20
#define NICE_WIDTH (MAX_NICE - MIN_NICE + 1)
/*
* Priority of a process goes from 0..MAX_PRIO-1, valid RT
* priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
* tasks are in the range MAX_RT_PRIO..MAX_PRIO-1. Priority
* values are inverted: lower p->prio value means higher priority.
*
* The MAX_USER_RT_PRIO value allows the actual maximum
* RT priority to be separate from the value exported to
* user-space. This allows kernel threads to set their
* priority to a value higher than any user task. Note:
* MAX_RT_PRIO must not be smaller than MAX_USER_RT_PRIO.
*/
#define MAX_USER_RT_PRIO 100
#define MAX_RT_PRIO MAX_USER_RT_PRIO
#define MAX_PRIO (MAX_RT_PRIO + NICE_WIDTH)
#define DEFAULT_PRIO (MAX_RT_PRIO + NICE_WIDTH / 2)
/*
* Convert user-nice values [ -20 ... 0 ... 19 ]
* to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
* and back.
*/
#define NICE_TO_PRIO(nice) ((nice) + DEFAULT_PRIO)
#define PRIO_TO_NICE(prio) ((prio) - DEFAULT_PRIO)
/*
* 'User priority' is the nice value converted to something we
* can work with better when scaling various scheduler parameters,
* it's a [ 0 ... 39 ] range.
*/
#define USER_PRIO(p) ((p)-MAX_RT_PRIO)
#define TASK_USER_PRIO(p) USER_PRIO((p)->static_prio)
#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO))
/*
* Convert nice value [19,-20] to rlimit style value [1,40].
*/
static inline long nice_to_rlimit(long nice)
{
return (MAX_NICE - nice + 1);
}
/*
* Convert rlimit style value [1,40] to nice value [-20, 19].
*/
static inline long rlimit_to_nice(long prio)
{
return (MAX_NICE - prio + 1);
}
#endif /* _SCHED_PRIO_H */
来源:CSDN
作者:oba没有马
链接:https://blog.csdn.net/u010317005/article/details/80531985