Linux 进程优先级

2017-01-12 kernel linux

优先级

静态优先级和 nice 值的区别。

只有 nice 值对用户可见,而静态优先级则隐藏在内核中,用户可以通过修改 nice 值间接修改静态优先级,而且只会影响静态优先级,不会影响动态优先级。对于普通进程来说,动态优先级是基于静态优先级算出来的。

静态优先级在进程描述符中为 static_prio 成员变量,该优先级不会随着时间而改变,内核不会修改它,只能通过系统调用 nice 去调整。

nice值是每个进程的一个属性,不是进程的优先级,而是一个能影响优先级的数字;取值范围为-20~19,默认为0。现在内核不再存储 nice 值,而是存储静态优先级 static_prio,两者在内核中通过两个宏进行转换。

#define NICE_TO_PRIO(nice)  (MAX_RT_PRIO + (nice) + 20)
#define PRIO_TO_NICE(prio)  ((prio) - MAX_RT_PRIO - 20)
#define TASK_NICE(p)        PRIO_TO_NICE((p)->static_prio)

上述的宏存在于 kernel/sched/sched.h 中,静态优先级的取值范围为 [MAX_RT_PRIO, MAX_PRIO-1] 也即 [100, 139]

动态优先级的值影响任务的调度顺序,调度程序通过增加或减少进程静态优先级的值来奖励 IO 消耗型进程或惩罚 CPU 消耗型进程,调整后的优先级称为动态优先级,在进程描述符中用 prio 表示,通常所说的优先级指的是动态优先级。

动态优先级的取值范围为 [0, MAX_PRIO-1] 也即 [0, 139],其中 [0, MAX_RT_PRIO-1] 也即 [0, 99] 为实时进程范围,数值越大表示优先级越小。

优先级可以通过 topps -o pid,comm,nice -p PID 或者 ps -el 查看,如果是实时进程就是静态优先级,如果是非实时进程,就是动态优先级。

# nice -n 10 commands               # 指定启动时的优先级为10
# nice -10 commands                 # 同上
# nice --10 commands                # 指定优先级为-10
# renice 10 -p PID                  # 设置已经启动进程的优先级,只有root可以设置为负值
# renice -10 PID                    # 设置为-10

可以修改 /etc/security/limits.conf 的值,指定特定用户的优先级 [username] [hard|soft] priority [nice value]

查看

在内核中,通过 0~139 来标示进程的优先级,其中 0~99 标识实时优先级,而 100~139 用于用户的进程,对应了 nice 的取值范围 -20~19 值越小优先级越高。

----- 可以通过普通用户降低优先级
$ nice -n 10 sleep 1000

----- 如果要提高优先级需要root权限
$ nice -n -10 sleep 1000

另外,通过 top 的 PR 会显示 PR=20+NI,而对于 ps 的参数则会比较复杂。

在 ps 中,会通过 PRI 或者 BAZ 列显示优先级,不过会根据参数不同,而显示的值也有所区别:A) priority 也就是 /proc/<PID>/stat 中的第 18 列;B) pri 计算方法为 39-priority;C) pri_baz 真实的优先级。

/proc/<PID>/stat 中的第 18 列,实际上是 task_struct->prio - 100 的值,可以参考 fs/proc/array.c 文件。