pri是内核动态计算的调度优先级值(越小越早调度),ni是用户可控的nice值,pri≈80+ni;二者共同决定普通进程调度权重,但pri会随进程行为动态调整,ni仅影响sched_other策略进程。

ps -l 输出里的 PRI 和 NI 到底代表什么
直接看 ps -l 输出,关键就两个字段:PRI 和 NI。它们不是同一个东西,但一起决定进程实际被调度的“权重”。
PRI 是内核计算出的**动态优先级值**,数值越小,进程越早被 CPU 调度;普通进程默认是 80,范围通常是 60~99(对应 nice -20 到 +19)。
NI 就是 nice 值,纯用户可控的修正项,只影响普通调度策略(SCHED_OTHER)下的进程。它不直接等于优先级,而是通过公式参与计算:PRI = 80 + NI(简化理解,实际受调度器细节影响略有浮动)。
常见误区:
- 把
NI当成最终优先级——错,NI只是偏移量,PRI才是调度器真正看的数 - 认为
ps -l显示的PRI永远固定——错,它会随进程行为(如睡眠/唤醒、CPU 使用率)被内核动态调整,但基线由NI锚定 - 用
top的 “PR” 列和ps -l的PRI对比时发现数值不同——正常,top默认显示的是“实时优先级”视角(含内核动态调整),而ps -l更接近静态基线
用 nice 启动进程时的限制和实际效果
nice 只在进程启动时生效,且普通用户只能调低优先级(即增大 NI,让 PRI 变大),不能提权。
例如:
nice -n 5 sleep 100
这个 sleep 进程的 NI 就是 5,PRI 大概率为 85(80 + 5)。
注意点:
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
-
nice -n -5会失败,除非你是 root——普通用户无权降低NI值 -
nice不改变已运行进程,只对子进程有效;它本质是设置fork()后子进程的初始NI - 即使你指定
nice -n 19,进程也不会“完全不被调度”,只是在同等条件下被排到队尾;调度器仍保障其最低执行时间片,避免饥饿
renice 修改运行中进程的 NI 值
renice 是修改已有进程 NI 的唯一标准命令,比 top 中按 r 更可控、可脚本化。
基本用法:
renice -n 10 -p 1234
把 PID 为 1234 的进程 NI 改为 10。
关键约束:
- 普通用户只能对自己拥有的进程调用
renice,且只能增加NI(即降低优先级) - root 用户可以任意修改任何进程的
NI,包括设为 -20 -
renice不会立即中断进程,新NI在下一次调度决策时生效,所以变化不是“瞬时可见”的 - 对实时进程(
SCHED_FIFO/SCHED_RR)调用renice无效——这些进程走另一套优先级体系,得用chrt
为什么 top 里看到的 PR 和 ps 的 PRI 数值经常对不上
这不是 bug,是设计使然。top 的 PR 列显示的是“**调度器当前赋予该进程的实际优先级**”,它融合了:NI、内核的动态补偿(如交互式进程提权)、CPU 使用历史、是否刚被唤醒等因子。
而 ps -l 的 PRI 更偏向“静态基线”,更接近 80 + NI 的理论值。
这意味着:
- 一个刚从 sleep 唤醒的交互式进程,在
top中PR可能显示为 75(被临时提权),但ps -l仍显示PRI为 80 -
top的NI列和ps -l的NI总是一致的——因为它是用户唯一能直接控制的输入项 - 如果你要写监控脚本判断“某个进程是否被降级”,别依赖
PR,盯住NI或用ps -o pid,ni,pri固定输出字段更可靠
最易被忽略的一点:所有基于 nice/renice 的调整,只对 SCHED_OTHER 策略有效。一旦进程被 chrt 设为实时调度,NI 就彻底失效,此时看 ps -eo pid,cls,pri 里的 cls(class)字段才能确认策略类型。










