顶部输出中的 nice 值和优先级之间的差异

Bel*_*dez 14 linux top

top默认情况下,列出两列。我很好奇有什么区别。我查看了手册页,但无法弄清楚:

优先事项:

   h: PR  --  Priority
      The priority of the task.
Run Code Online (Sandbox Code Playgroud)

不错的价值:

   i: NI  --  Nice value
      The nice value of the task.  A negative nice value means higher  priority,
      whereas  a  positive  nice value means lower priority.  Zero in this field
      simply means priority will not be adjusted in determining  a  task’s  dis-
      patchability.
Run Code Online (Sandbox Code Playgroud)

我知道Nice 值与内核的 CPU 调度程序队列有关;那么优先级是什么意思呢?可能是关于 I/O 的?

小智 31

不同之处在于PR是内核内部进程的真正优先级,而NI只是内核提示进程应该具有的优先级。

在大多数情况下,PR值可以通过以下公式计算:PR = 20 + NI。因此,niceness 为 3 的进程的优先级为 23 (20 + 3),niceness 为 -7 的进程的优先级为 13 (20 - 7)。您可以通过运行命令来检查第一个nice -n 3 top。它将显示顶部进程具有NI 3PR 23。但是要nice -n -7 top在大多数 Linux 系统中运行,您需要具有 root 权限,因为实际上PR值越低,实际优先级就越高。因此,具有PR 13的进程比具有标准优先级PR 20 的进程具有更高的优先级. 这就是为什么你需要成为 root。但是可以在/etc/security/limits.conf 中配置非 root 进程允许的最小 niceness 值。

理论上内核可以自己改变PR值(但不能改变NI)。例如,如果某个进程消耗过多的 CPU,它可能会降低优先级,或者如果该进程由于其他更高优先级的进程而没有机会运行很长时间,它可能会提高该进程的优先级。在这些情况下,内核会更改PR值,而NI将保持不变,因此公式“PR = 20 + NI”将不正确。所以NI值可以解释为内核提示进程应该具有什么优先级,但内核可以根据情况自行选择实际优先级(PR值)。但通常公式“PR = 20 + NI”是正确的。

内核如何更改优先级的确切规则尚不清楚。setpriority(改变nice值的函数)手册说:

更改 nice 值的效果可能因有效的进程调度算法而异。

Pthread手册说如下:

动态优先级基于 nice 值(由 nice(2)、setpriority(2) 或 sched_setattr(2) 设置),并且在线程准备好运行但被调度程序拒绝运行的每次量子时增加。

似乎PR值对应于动态优先级。

NI值的范围是-20..19。因此,PR值可以具有从0 (20 - 20) 到39 (20 + 19) 的值。但它仅适用于具有默认调度策略 ( SHED_OTHER )的进程。也可能存在具有所谓“实时”调度策略的进程。这些策略是SCHED_RRSCHED_FIFO。此类进程的PR值小于 0。您可以通过运行chrt -r 1 top命令(需要是 root)来检查这一点。在顶部的过程将有PR -2。你甚至可以运行chrt -r 90 top在这种情况下顶部过程将有PR -91

对于SCHED_RR进程,PR值似乎可以通过以下公式计算:

PR = - 1 - sched_rr_priority

因此一个SCHED_RR进程至少有PR -1这意味着任何SCHED_RR进程具有比任何SCHED_OTHER更高的优先级。这对应于 pthread 手册:

SCHED_FIFO 只能用于高于 0 的静态优先级,这意味着当 SCHED_FIFO 线程变为可运行时,它将始终立即抢占任何当前正在运行的 SCHED_OTHER、SCHED_BATCH 或 SCHED_IDLE 线程。

SCHED_RR 是 SCHED_FIFO 的简单增强。上面针对 SCHED_FIFO 描述的所有内容也适用于 SCHED_RR,

实时进程的优先级称为静态优先级,内核无法更改。所以正PR值可以被视为动态优先级用于非实时(SCHED_OTHERSCHED_BATCH)工艺和负PR值作为用于实时进程静态优先级(SCHED_RRSCHED_FIFO)。

我也尝试运行nice -n 10 chrt -r 50 top(和chrt -r 50 nice -n 10 top)。该NI值为10,但PR仍是-51。所以看起来NI值不会影响SCHED_RR进程的优先级。这对应于setpriority手册:

任何使用 SCHED_FIFO 或 SCHED_RR 的进程或线程都不应受到调用 setpriority() 的影响。这不被视为错误。随后恢复到 SCHED_OTHER 的进程不需要使其优先级受此类 setpriority() 调用的影响。

一个有趣的笔记。如果您运行chrt -r 99 top,您将在PR列中看到RT值而不是数字。

  PID 用户 PR NI VIRT RES SHR S %CPU %MEM TIME+ 命令
28489 根 RT 0 2852 1200 896 R 0 0.1 0:00.01 顶部

我不认为这意味着这个过程现在很特别。我认为这意味着top只是不打印-100,因为打印需要 4 个字符。

您还可以在所有示例中使用htop而不是top,这会更方便。ps -l也可以用,但是区分实时和非实时优先级的基点不是0,而是60,所以nice -n -20 ps -l会打印

FS UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 R 0 28983 28804 0 60 -20 - 1176 - pts/6 00:00:00 ps

  • @BelminFernandez 我认为让这个答案“被接受”是公平的。 (2认同)

Ign*_*ams 10

nice 值是一种“全局”机制,而优先级现在与任务切换器相关。