03 进程的 360° 展示 - ps 和进程状态
ps命令用于显示当前系统中运行的进程信息。ps是 "Process Status" 的缩写,它提供了关于进程的各种详细信息,包括进程 ID(PID)、CPU 使用率、内存使用率、进程状态等。
常用选项
| 选项 | 描述 |
|---|---|
-a | 显示所有与终端相关的进程(除去会话引导进程) |
-o | 自定义显示信息字段,如:ps -o pid,user,%cpu,command |
-e 或 -A | 显示所有进程 |
-f | 显示完整格式的输出,包括父进程、启动时间等详细信息 |
-l | 显示长格式的输出 |
-u <username> | 显示指定用户的进程 |
-p <pid> | 显示指定 PID 的进程 |
-C <command> | 显示指定命令的进程 |
aux | 类 Unix 风格的命令,显示系统中所有进程及其详细信息。包括每个进程的用户、CPU、内存使用情况等 |
-ef | 以标准格式显示所有进程的详细信息 |
输出字段
| 字段 | 描述 |
|---|---|
| PID | 进程 ID,每个进程在系统中的唯一标识符 |
| TTY | 进程关联的终端设备 |
| TIME | 进程使用的 CPU 时间 |
| CMD | 启动进程的命令 |
| USER | 进程的所属用户 |
| %CPU | 进程的 CPU 使用率 |
| %MEM | 进程的内存使用率 |
常用示例
ps:显示当前终端下的所有进程,只包括当前用户的会话进程。ps -[Ae]:显示所有进程,包括运行态和非运行态。ps -[Ae] | wc -l:显示所有进程的总数(与top命令显示的进程数一致)。ps -a:显示与终端相关的所有进程,排除会话引导进程和非终端控制的进程。ps -aux:显示所有进程,包括其他终端和无终端控制的进程。ps -aux | less:分页显示所有进程信息(包括运行态和非运行态)。ps -u [user]:显示用户名为[user]的所有进程信息。ps -e | grep '[^?]':只显示 TTY 字段为非?的进程,即有终端关联的所有进程。ps -[Ae]f:显示所有进程的信息,包括命令行等详细信息。-f表示全格式显示。ps -[Ae]Tf:以线程为统计单位显示所有进程及其线程信息,T表示线程模式 (Thread)。ps -p [PID]:显示特定进程的详细信息。ps aux | grep [keywords]:显示与指定关键字[keywords]相关的进程,通过grep进行过滤。ps -eo pid,stat,pri,uid --sort uid:显示指定字段(PID、状态、优先级、用户 ID),并根据 UID 进行排序。ps -eTf | wc -l:统计所有线程的数量,-T表示按线程显示。ps -ef | wc -l:统计所有进程的数量,-e显示所有进程,-f以完整格式显示。ps aux --sort=-%cpu:按 CPU 使用率排序,查看占用 CPU 最高的进程。ps aux --sort=-%mem:按内存使用率排序,查看占用内存最高的进程。ps aux --sort time:按进程使用 CPU 时间排序,查看占用 CPU 时间最长的进程。
TIP
ps -aux是兼容性选项,实际上是 BSD 风格的参数,推荐使用ps aux(不带-)。ps -e | grep '[^?]'用于过滤出 TTY 字段不为?的进程。?表示没有终端控制(一般为守护进程、内核进程等,即系统启动就运行的进程)。ps后的选项和参数之间可以有空格,使用时要注意区分。
进程状态
进程在运行时可能会处于不同的状态。可以通过 ps 命令的输出中的 STAT 列查看每个进程的状态。
| 状态码 | 描述 |
|---|---|
R (Running or Runnable) | 运行态。进程正在运行或准备运行,等待 CPU 时间片分配 |
S (Sleeping) | 睡眠态。进程正在等待某个事件(如 I/O 操作完成)或信号 |
S+ (Foreground Sleep) | 前台睡眠态。进程在前台终端处于可中断睡眠状态 |
D (Uninterruptible Sleep) | 不可中断睡眠态。进程正在等待 I/O 操作,无法被信号中断(如磁盘 I/O)。这种状态下的进程不能被信号中断(如等待磁盘 I/O),无法处理信号 |
T (Stopped) | 停止态。进程被暂停或停止,通常由于接收到 SIGSTOP、SIGTSTP 信号,或者被调试器暂停 |
Z (Zombie) | 僵尸态。进程已经终止,但其父进程尚未调用 wait() 系统调用来获取子进程的退出状态。僵尸进程不会占用系统资源,但它的进程描述符仍然存在,等待父进程清理 |
X (Dead) | 进程已经终止,但尚未被父进程回收 |
I (Idle) | 内核线程,通常是空闲线程,不占用 CPU 资源 |
附加标志
除了上面的基本状态,STAT 列还可以包含一些额外的标志,用于描述进程的更多详细信息。
| 附加标志 | 描述 |
|---|---|
< (High-priority) | 高优先级进程。通常是实时任务,优先级比普通进程高。 |
N (Low-priority) | 低优先级进程。进程的优先级低于普通进程。 |
l (Multi-threaded) | 多线程进程。该进程是一个多线程进程,使用多个线程同时执行任务。 |
s (Session Leader) | 会话领导者。通常是用户登录时创建的第一个进程(如终端会话的主进程)。 |
+ (Foreground Process Group) | 前台进程组中的进程。属于前台终端控制的进程组,可以接收来自终端的信号(如 SIGINT)。 |
L (Paging Locked) | 有分页锁定。进程的部分内存被锁定,不能被交换到硬盘。 |
ps -l
bash
➜ ~ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 856379 856378 0 80 0 - 2444 sigsus pts/0 00:00:00 zsh
4 R 0 889229 856379 0 80 0 - 2523 - pts/0 00:00:00 ps
# F: 4 表示进程具有超级用户权限。
# S: zsh 进程处于睡眠态 (S),ps 进程处于运行态 (R)。
# UID: 两个进程的 UID 均为 0,表示它们由 root 用户启动。
# PID: 856379 是 zsh 进程的唯一标识符,889229 是 ps 进程的唯一标识符。
# PPID: 856378 是 zsh 进程的父进程 ID,856379 是 ps 进程的父进程 ID(zsh)。
# C: 0 表示两个进程的 CPU 占用率均为 0%。
# PRI: 80 表示两个进程的优先级,默认优先级为 80。
# NI: 0 表示两个进程的 Nice 值均为 0,即没有调整优先级。
# ADDR: - 表示两个进程均没有显示内存驻留地址(用户进程通常为 `-`)。
# SZ: zsh 进程使用了 2444 页的虚拟内存,ps 进程使用了 2523 页的虚拟内存。
# WCHAN: zsh 进程当前正在等待信号处理 (sigsus),而 ps 进程未在等待任何资源 (-)。
# TTY: 两个进程均与伪终端 pts/0 关联。
# TIME: 两个进程的 CPU 使用时间均为 00:00:00(即它们没有消耗显著的 CPU 时间)。
# CMD: zsh 是启动的 shell,ps 是用于显示进程信息的命令。| 列名 | 描述 |
|---|---|
F | 进程标志(Flags)。表示与进程相关的各种系统级标志。常见的标志如 4(使用了超级用户权限)。 |
S | 进程状态(State)。表示进程的当前状态,常见的值如 R(运行)、S(睡眠)等。 |
UID | 用户 ID。启动该进程的用户的 ID。0 表示超级用户(root)。 |
PID | 进程 ID。当前进程的唯一标识符。 |
PPID | 父进程 ID。启动当前进程的父进程的 ID。 |
C | CPU 占用率。当前进程占用的 CPU 资源的百分比。 |
PRI | 进程优先级(Priority)。进程的内核调度优先级,值越小优先级越高。 |
NI | Nice 值。进程的优先级调整值,用户可以通过调整 nice 值来改变进程的优先级。-20 为最高优先级,19 为最低。 |
ADDR | 内存地址。进程的内存驻留地址。对于内核线程,这里会显示内核的函数地址。用户进程则通常显示为 -。 |
SZ | 虚拟内存使用量(Size),以页面为单位,表示进程使用的虚拟内存大小。每个页面的大小通常是 4KB。 |
WCHAN | 等待通道(Wait Channel)。如果进程在等待某些资源(如 I/O 操作),这里会显示等待的函数地址或名称。- 表示未等待。 |
TTY | 终端类型。表示进程所属的终端设备。pts/0 表示伪终端。? 表示无终端(一般为守护进程、内核进程等,即系统启动就运行的进程)。 |
TIME | 进程使用的总 CPU 时间。表示进程从启动到当前为止,消耗的 CPU 时间,格式为 分钟:秒。 |
CMD | 启动进程的命令及其参数。显示执行该进程的命令名称。 |
ps aux
bash
➜ ~ ps aux | head -3
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 171912 11392 ? Ss Jul23 7:43 /usr/lib/systemd/systemd --system --deserialize 41
root 2 0.0 0.0 0 0 ? S Jul23 0:03 [kthreadd]| 列名 | 描述 |
|---|---|
USER | 用户名,显示启动该进程的用户 |
PID | 进程 ID,系统中每个进程的唯一标识符 |
%CPU | 进程的 CPU 使用率(百分比),显示进程占用的 CPU 时间相对于总时间的百分比 |
%MEM | 进程的内存使用率(百分比),显示进程占用的物理内存量相对于系统总内存的百分比 |
VSZ | 虚拟内存集大小(Virtual Memory Size),以 KB 为单位,表示进程的虚拟地址空间的大小 |
RSS | 常驻集大小(Resident Set Size),以 KB 为单位,表示进程占用的实际物理内存的大小 |
TTY | 终端设备,表示进程关联的终端。? 表示没有终端控制(一般为守护进程、内核进程等,即系统启动就运行的进程) |
STAT | 进程的状态代码,如 R(运行)、S(睡眠)、Z(僵尸进程)等 |
START | 进程的启动时间,显示进程开始的时间或日期(如系统运行较久,会显示启动的日期) |
TIME | 进程使用的总 CPU 时间,表示进程从启动到当前为止使用的 CPU 时间,格式为“分钟:秒” |
COMMAND | 启动进程的命令及参数,可能会显示完整的命令行或截断 |
TIP
- TTY:由虚拟控制台、串口以及伪终端设备组成的终端设备;若为
?,一般为守护进程、内核进程等,即系统启动就运行的进程! - TIME:总消耗的 CPU 时间,若单进程一直满负荷运行,则总消耗 CPU 时间为程序启动时间到此时的墙上时间;若为多线程,则总消耗 CPU 时间可能超过墙上时间;
- COMMAND:如果进程名形如
[command],则表明是内核进程,否则为用户进程; - VSZ:实际内存占用量
<虚拟内存使用量<实际物理机的内存使用量
ps -ef
bash
➜ ~ ps -ef | head -3
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jul23 ? 00:07:43 /usr/lib/systemd/systemd --system --deserialize 41
root 2 0 0 Jul23 ? 00:00:03 [kthreadd]| 列名 | 描述 |
|---|---|
UID | 用户 ID,显示启动该进程的用户。 |
PID | 进程 ID,系统中每个进程的唯一标识符。 |
PPID | 父进程 ID,表示该进程的父进程的 ID。 |
C | CPU 占用率,显示进程的 CPU 使用情况(百分比)。通常是短期的 CPU 使用率。 |
STIME | 进程的启动时间,显示进程启动的时间(日期或具体时间)。 |
TTY | 终端设备,表示进程关联的终端。? 表示没有终端控制(后台进程)。 |
TIME | 进程消耗的总 CPU 时间,格式为“分钟:秒”。 |
CMD | 启动该进程的命令及参数,可能会被截断(特别是在 ps -ef 输出中)。 |
ps aux 和 ps -ef 对比
ps aux更适合查看进程的资源使用情况(如 CPU 和内存占用),其输出格式来源于 BSD 风格。ps -ef更适合查看进程的层级关系和启动时间等信息,输出格式遵循 UNIX/System V 风格。
ps aux | ps -ef | |
|---|---|---|
| 命令风格 | BSD 风格 | UNIX/System V 风格 |
| 输出字段 | 包括用户(USER)、进程 ID(PID)、CPU、内存使用率(%CPU, %MEM)、命令名(COMMAND)等 | 包括用户(UID)、父进程 ID(PPID)、进程 ID(PID)、启动时间(STIME)、命令名(CMD)等 |
| 优先级显示 | 显示 CPU 和内存使用率(%CPU, %MEM)。 | 不显示 CPU 和内存使用率。 |
| TTY(终端)显示方式 | 显示终端的具体名称或者 ?(没有控制终端)。 | 显示终端的具体名称或者 ?(没有控制终端)。 |
| 完整路径的显示 | COMMAND 字段通常显示完整的命令行参数。 | CMD 字段可能截断命令行参数(受终端宽度限制)。 |
| 输出条目 | 不会显示 PPID(父进程 ID)字段。 | 显示 PPID 字段。 |
| 默认显示范围 | ps aux 显示所有用户的所有进程。 | ps -ef 显示所有用户的所有进程。 |
| 常用场景 | 主要用于查看 CPU 和内存占用率高的进程。 | 主要用于查看进程层级(如父子进程关系)。 |
| 启动时间格式 | ps aux 中的 START 显示进程的启动时间(小时和分钟)。 | ps -ef 中的 STIME 显示简化的启动时间(日期或时间)。 |
bash
➜ ~ ps aux | tail -n +2 | wc -l
128
➜ ~ ps -ef | tail -n +2 | wc -l
129实验代码
实验代码
bash
➜ ~ ps # 查看当前系统进程
PID TTY TIME CMD
856379 pts/0 00:00:00 zsh
914362 pts/0 00:00:00 ps
➜ ~ stress-ng -c 1 & # 启动一个 CPU 压力测试工具
[1] 914557
➜ ~ stress-ng: info: [914557] defaulting to a 1 day, 0 secs run per stressor
stress-ng: info: [914557] dispatching hogs: 1 cpu
➜ ~ ps # 查看当前系统进程,可以看到测试进程
PID TTY TIME CMD
856379 pts/0 00:00:00 zsh
914557 pts/0 00:00:00 stress-ng
914561 pts/0 00:00:04 stress-ng-cpu
914594 pts/0 00:00:00 ps
➜ ~ kill %1 # 结束作业号为 1 的进程,也就是测试进程
➜ ~ stress-ng: info: [914557] skipped: 0
stress-ng: info: [914557] passed: 0
stress-ng: info: [914557] failed: 1: cpu (1)
stress-ng: info: [914557] metrics untrustworthy: 0
stress-ng: info: [914557] unsuccessful run completed in 15.46 secs
[1] + 914557 exit 2 stress-ng -c 1
➜ ~ ps # 再次查看当前系统进程,可以看到测试进程已经结束
PID TTY TIME CMD
856379 pts/0 00:00:00 zsh
914776 pts/0 00:00:00 ps