调度器真正使用的是pri,但用户只能通过调整ni(nice值)间接改变它,公式为pri=80+ni;ni范围是-20~19,数值越小优先级越高,普通用户仅能设ni≥0。

ps -l 输出里 PRI 和 NI 到底哪个才是“优先级”
真正被调度器使用的优先级是 PRI,但它不是你直接改的值;你实际能控制的是 NI(nice 值),PRI 会按公式 PRI = 80 + NI 动态算出来。所以看到 PRI 是 95,不代表它被“设成 95”,而是 NI 是 15 导致的。
常见误解是以为 PRI 越小越好,确实如此——但普通用户无法直接写 PRI,只能通过调整 NI 间接影响它。比如 NI = -10 → PRI = 70,比默认的 80 更高优先级;NI = 19 → PRI = 99,几乎排在队尾。
-
ps -l显示当前终端下进程,PRI和NI两列并列出现,别只盯PRI忽略NI -
ps -eo pid,ni,pri,comm --sort=-ni按NI降序排,能快速找出最“闲”的进程(NI越大越靠前) - 如果
NI显示为-,说明该进程用了实时调度策略(如SCHED_FIFO),nice对它完全无效
用 nice 启动新进程时参数写法容易错在哪
nice 命令本身不带 -n 也能用,但格式极易混淆: nice -10 cmd 等价于 nice -n -10 cmd,而 nice 10 cmd 是 nice -n 10 cmd —— 正负号必须显式写出,否则默认当正数处理。
更关键的是权限限制:普通用户只能设 NI ≥ 0,即不能用负值提升自己进程的优先级;哪怕加了 sudo,也得确认当前 shell 是否允许非 root 用户提权调用 nice(部分系统会禁用)。
- 正确写法:
nice -n 5 tar -cf archive.tar /data(降低优先级) - 错误写法:
nice -5 cmd(普通用户执行等同于nice -n 5 cmd,不是提升) - 想用负值?必须
sudo nice -n -15 ./app,且目标程序未被 cgroups 限制(比如 systemd service 默认有 CPUWeight)
renice 修改运行中进程,为什么有时 ni 不变
执行 renice -n 8 -p 12345 后查 ps -o pid,ni,comm -p 12345 发现 NI 没变,大概率是以下三种情况之一:
- 进程处于不可中断状态(
D状态),比如正在做磁盘 IO 或等待内核锁,此时renice会静默失败,ps仍显示旧值 - 进程属于其他用户,且你不是 root —— 普通用户只能对自身进程调高
NI(即让其更“谦让”),不能设负值,也不能碰别人进程 - 进程被 cgroups v2 的
cpu.weight或cpu.max限制,内核调度器会忽略nice值,优先服从 cgroup 配置
验证方式:ps -o pid,state,ni,comm -p 12345 先看 state 是否为 R 或 S;再查 cat /proc/12345/cgroup 看是否在某个 cpu controller 下。
top 里按 r 调整后,PRI 列没更新?
top 中按 r → 输入 PID → 输入新 NI 值,操作看似完成,但 PRI 列可能延迟刷新或根本不更新,原因很实在:
-
top默认刷新间隔是 3 秒,刚改完立刻看可能还是旧值;按W保存配置、q退出再重进top更可靠 - 某些发行版(如 RHEL 8+)默认启用 cgroups v2,
top的PRI列显示的是调度器最终采用的“有效优先级”,它可能已脱离80 + NI公式 -
top的NI列其实是只读显示,你输的值实际作用于内核,但界面不会回显确认,建议改完立刻用ps -o pid,ni,comm -p PID单独验证
最稳妥的验证链是:renice -n X -p PID → sleep 0.1 → ps -o pid,ni,pri,comm -p PID。别依赖 top 界面的实时性。
真正麻烦的不是怎么调,而是调了之后谁还管它——比如一个 NI = -10 的后台服务,重启后自动回到 NI = 0;systemd 服务还得配 IOSchedulingPriority= 或 Nice= 才能固化。这类细节,一不留神就白调。











