Skip to content

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)停止态。进程被暂停或停止,通常由于接收到 SIGSTOPSIGTSTP 信号,或者被调试器暂停
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。
CCPU 占用率。当前进程占用的 CPU 资源的百分比。
PRI进程优先级(Priority)。进程的内核调度优先级,值越小优先级越高。
NINice 值。进程的优先级调整值,用户可以通过调整 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。
CCPU 占用率,显示进程的 CPU 使用情况(百分比)。通常是短期的 CPU 使用率。
STIME进程的启动时间,显示进程启动的时间(日期或具体时间)。
TTY终端设备,表示进程关联的终端。? 表示没有终端控制(后台进程)。
TIME进程消耗的总 CPU 时间,格式为“分钟:秒”。
CMD启动该进程的命令及参数,可能会被截断(特别是在 ps -ef 输出中)。

ps aux 和 ps -ef 对比

  • ps aux 更适合查看进程的资源使用情况(如 CPU 和内存占用),其输出格式来源于 BSD 风格。
  • ps -ef 更适合查看进程的层级关系和启动时间等信息,输出格式遵循 UNIX/System V 风格。
ps auxps -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