【linux】进程优先级、nice系统中的nice值和nice time,top中的PR和ps中的PRI

版权声明:原创文章,转载注明出处! https://blog.csdn.net/u010317005/article/details/80531985

背景知识

    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)优先级范围
    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.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 */

猜你喜欢

转载自blog.csdn.net/u010317005/article/details/80531985