在多任务系统中,CPU 是一种共享资源,内核调度器负责决定哪个进程在何时使用 CPU。虽然调度器很智能,但有时用户需要显式地“建议”内核某个进程更重要或不那么重要。Linux 通过 nice 值(调度优先级)来接收这种建议,并用 nice 和 renice 这两个命令来查看和调整。
1. 什么是 nice 值
nice 值的命名很形象:一个“友好”的进程会主动让出资源,把 CPU 时间留给其他进程。因此,nice 值越高,进程就越“谦让”,实际获得的 CPU 时间相对越少;nice 值越低(负数),进程就越“不客气”,调度优先级也越高。
nice 值的合法范围通常是 -20(最高优先级)到 19(最低优先级)。普通用户只能将 own 进程的 nice 值设为 0 到 19,也就是说只能让自己的进程更“谦让”;而 root 用户可以将 nice 值设为 -20 到 19 之间的任意数,既能降低也能提升优先级。
2. 查看当前的 nice 值
top 和 ps 都能显示 nice 值。在 top 输出的默认视图里,NI 列就是 nice 值;在 ps -l (长格式列表)中,NI 列同样展示了每个进程的 nice 值。
ps -l
# F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
# 0 S 1000 1234 1100 0 80 0 - 5723 wait pts/0 00:00:00 bash
# 0 R 1000 5678 1234 90 99 19 - 2134 - pts/0 00:00:12 cpu_hog
上面第二个进程的 NI 为 19,表示它是一个低优先级的 CPU 密集型任务。PRI 列是内核实际使用的动态优先级,它会结合 nice 值和其他因素计算出来,数字越小优先级越高,一般用户无需直接关心 PRI。
3. 用 nice 以指定优先级启动新进程
nice 命令可以让一个程序在启动时就带上期望的优先级。默认情况下(不带 -n 选项),nice 会以 nice 值 10 来运行程序。如果需要指定别的值,可以用 -n 参数:
# 以最低优先级运行一个 CPU 密集压缩任务
nice -n 19 gzip huge_log_file
# 普通用户试图使用负值会被拒绝
nice -n -5 myprogram
# nice: cannot set niceness: Permission denied
日常使用中,这一功能非常适合处理那些需要长时间运行但又不想影响交互式工作的后台任务,比如文件校验、数据备份或视频转码。
4. 用 renice 调整已在运行进程的优先级
如果一个进程已经开始执行,可以用 renice 来动态调整其 nice 值。语法是 renice [新nice值] [目标],目标可以是 PID、用户名或组 ID。
# 将 PID 1234 的进程优先级调至最高(仅 root 允许负数)
sudo renice -10 -p 1234
# 将用户 bob 的所有进程优先级设为 5
sudo renice 5 -u bob
# 普通用户只能对自己拥有的进程提升 nice 值(降低优先级)
renice 10 -p 5678
renice 成功执行后不会有详细输出,但可以通过 echo $? 检查返回值(0 表示成功),或再次用 ps -l 确认 NI 列已更改。在使用 sudo 时务必小心,把关键的守护进程优先级设置过低可能导致服务卡顿。
5. 实际场景与注意事项
- 后台批处理任务:如果你需要在服务器上运行一个耗时数小时的数据分析脚本,可以
nice -n 19 ./analysis.sh,这样它就会尽可能利用闲置 CPU,却不会拖慢正在服务的 Web 请求。 - 临时给服务提权:某个数据库备份进程在午夜运行时,如果发现备份速度过慢,可以用
renice临时提升其优先级,备份完成后再调回正常值。 - 不是实时保证:nice 值只是一个“建议”,内核的完全公平调度器(CFS)会综合考虑进程历史行为、cgroup 限制等因素。将 nice 值设为 -20 并不等于独占 CPU,只能保证该进程在竞争时相对于其他普通进程更容易被调度选中。
- 现代多核环境:在多核 CPU 上,nice 值仍然有效,只是竞争维度变成了每个 CPU 核心上的运行队列。一个高优先级的单线程进程不太可能影响到其他空闲核心上的工作负载。
总而言之,nice 和 renice 是手动干预 CPU 时间分配的最直接工具。它们简单、透明,只要学会查看和调整 nice 值,就能在许多场景下让系统更合理地分配计算资源,既保证交互流畅,又不浪费空闲算力。