优先级
静态优先级和 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]
为实时进程范围,数值越大表示优先级越小。
优先级可以通过 top
、ps -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
文件。