【linux】进程优先级、nice系统中的nice值和nice time,top中的PR和ps中的PRI
出处:https://blog.****.net/u010317005/article/details/80531985
linux内核目前实现了6中调度策略(即调度算法), 用于对不同类型的进程进行调度, 或者支持某些特殊的功能,其中SCHED_NORMAL和SCHED_BATCH调度普通的非实时进程, SCHED_FIFO和SCHED_RR和SCHED_DEADLINE则采用不同的调度策略调度实时进程, SCHED_IDLE则在系统空闲时调用idle进程.
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)优先级范围
MAX_USER_RT_PRIO的值(默认为100)让用户态的优先级范围区别于实时优先级的最大值(99)。这样设计的好处是任何内核态线程的优先级都大于用户态的任务线程。注意:最大实时优先级(MAX_RT_PRIO)不得小于用户态优先级(MAX_USER_RT_PRIO)。
用户的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
ps中的PRI也是表示优先级,通过ps -el可以显示出来,例如
这里的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.****.net/gatieme/article/details/51719208
https://blog.****.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 */
---------------------