在 Linux 多任务环境中,进程优先级和切换是保障系统高效运行的核心机制。优先级决定了 CPU 资源的分配顺序,让关键任务优先获得执行机会;而进程切换则实现了 "单 CPU 并发多任务" 的核心逻辑,让多个进程看似 "同时" 运行。本文聚焦进程优先级与切换的核心知识点,从基础概念、实战操作到底层原理,层层递进帮你吃透这两个关键机制,学会在实际开发中优化进程资源分配、减少切换开销。
一. 进程优先级:CPU 资源的 "分配权重"
进程优先级是操作系统分配 CPU 时间片的核心依据,优先级越高,进程获得 CPU 执行的概率越大。Linux 中优先级的管理核心是PRI(静态优先级)和NI(nice 值),两者协同决定进程的实际执行优先级。
✅️ 核心概念:PRI 与 NI:
(1)PRI(Priority):静态优先级
表示进程的基础优先级,值越小,优先级越高;
Linux 普通进程的 PRI 范围为 100~139,进程创建时由内核默认分配(默认值 120);
用户无法直接修改 PRI,只能通过调整 NI 间接改变。
(2)NI(Nice 值):优先级修正值
用于调整进程的实际优先级,取值范围为-20~19(共 40 个级别);
实际优先级计算公式:PRI(new) = PRI(old) + NI;
核心特性:
NI 为负数:PRI 降低,优先级升高(如 NI=-5 → PRI=115);
NI 为正数:PRI 升高,优先级降低(如 NI=10 → PRI=130);
NI=0:优先级保持默认,不做调整。
二. 优先级的查看方式
(1)ps 命令(静态查看)
bash复制代码
# 查看当前终端进程的优先级信息
ps -al
输出关键信息解析:
PRI:当前进程的静态优先级;
NI:当前进程的 nice 值;
PID:进程 ID(后续调整优先级需用到)。
UID:表明这个进程是谁(那个用户)启动的
(2)top 命令(动态查看)
bash复制代码
top
进入界面后,按 f 键可添加PRI和NI字段;
实时观察进程优先级变化,适合监控高负载场景下的进程状态。
三. 优先级的调整方法补充(实战重点):
Linux 提供多种方式调整进程 nice 值,间接修改优先级,核心原则是 "只能调整 NI,无法直接改 PRI"。
#include <sys/resource.h>
#include <stdio.h>
int main() {
// 获取当前进程的nice值(PRIO_PROCESS表示进程级,0表示当前进程)
int ni = getpriority(PRIO_PROCESS, 0);
printf("初始nice值:%d\n", ni);
// 设置当前进程nice值为-3
setpriority(PRIO_PROCESS, 0, -3);
printf("修改后nice值:%d\n", getpriority(PRIO_PROCESS, 0));
return 0;
}
优先级调整的注意事项:
权限限制 :普通用户只能将 NI 调大(降低优先级),root 用户可全范围(-20~19)调整;
避免过度提升:高优先级进程会抢占更多 CPU,可能导致其他进程 "饥饿"(长期无法执行);
四. 补充概念:竞争,独立,并行,并发
竞争性:系统进程数目众多,而 CPU 资源只有少量,甚至 1 个,所以进程之间是具有竞争属性的。为了高效的完成任务,更合理竞争相关资源,便具有了优先级
独立性:多进程运行,需要独立各种资源,多进程运行期间互不干扰
并行:多个进程在一个 CPU 下分别,同时进行运行,这称之为并行
并发:多个进程在一个 CPU 下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发
五. 进程切换:并发的底层实现
进程切换(上下文切换)是指 CPU 从一个进程切换到另一个进程执行的过程,是 Linux 实现 "单 CPU 并发多任务" 的核心机制。
CPU上下文切换:其实际含义是任务切换,或者 CPU 寄存器切换。当多任务内核决定运行另外的任务时,它保存正在运行任务的当前状态,也就是 CPU 寄存器中的全部内容。这些内容被保存在任务自己的堆栈中,入栈工作完成后就把下一个将要运行的任务的当前状况从该任务的栈中重新装入 CPU 寄存器,并开始下一个任务的运行,这一过程就是 context switch。
CPU 寄存器是进程执行的 "临时工作台",存储着进程当前的执行状态(程序计数器、寄存器值、栈指针等)。切换时需完成两步关键操作: