当前位置:首页>Linux>Linux下如何分析进程状态?

Linux下如何分析进程状态?

  • 2026-10-11 06:28:54
Linux下如何分析进程状态?

1. 文档目的

本文介绍如何使用perf stat、perf top、perf sched 和 perf lock观察 Linux 进程的 CPU 使用、函数热点、调度延迟和锁竞争,从而判断进程的主要运行瓶颈。

1.1 perf 工具简介

perf是Linux 内核提供的性能分析工具集,主要通过硬件性能计数器、软件事件、tracepoint 和采样机制观察系统或进程的运行行为。它适合回答“CPU 时间花在哪里”、“程序是否真的在跑 CPU”、“线程是否被调度延迟”、“是否存在锁竞争”等问题。

perf top 看到的是 on-CPU 热点,对 I/O 等待、条件变量等待、队列阻塞等 off-CPU 问题并不敏感;perf lock 主要观察 Linux 内核锁事件,不能完整代表用户态 pthread_mutex 竞争;perf stat 只能给出方向性指标,通常需要结合业务吞吐、延迟、丢包率和采集时的负载条件一起判断。

推荐按照以下顺序排查:

perf stat -> perf top/perf record -> perf sched -> perf lock/futex

1.2 perf 排查流程图

2. 分析前准备

2.1 获取目标进程和线程

pid=$(pidof worker)ps -p ”$pid” -o pid,ppid,stat,psr,pcpu,pmem,etime,commps -T -p ”$pid” -o pid,tid,psr,stat,pcpu,comm

其中:

  • PID 表示进程 ID。
  • TID 表示线程 ID。
  • PSR 表示线程当前或最近运行的 CPU。
  • STAT 中 R 表示运行或等待 CPU,S 表示可中断睡眠,D 表示不可中断睡眠。

如果进程长期处于 D 状态,应优先检查磁盘、网络文件系统、驱动或其他内核 I/O,单独使用 CPU 热点分析通常无法找到根因。

2.2 确认 perf 和事件支持情况

perf --versionsudo perf list

perf最好与当前运行内核版本匹配。不同发行版和 perf 版本支持的参数、硬件事件、tracepoint 可能不同,执行前可以使用 <命令> --help 确认。

生产环境建议先采集 10 到 30 秒,并观察采集本身带来的 CPU 和存储开销。

3. 使用 perf stat 判断瓶颈方向

3.1 基础采集

sudo perf stat -p ”$pid” -e \task-clock,context-switches,cpu-migrations,page-faults,cycles,instructions,\cache-references,cache-misses,branches,branch-misses -- sleep 30

也可以使用详细统计模式:

sudo perf stat -d -p ”$pid” -- sleep 30

针对单个关键线程采集:

sudo perf stat -t -- sleep 30

3.2 关键指标解释

IPC 的含义为:

IPC = instructions / cycles

IPC 没有适用于所有程序的统一正常值,应在相同硬件、相同流量和相同业务模型下进行对比。

3.3 初步判断

3.4 perf stat 瓶颈判断图

4. 使用 perf top 定位实时 CPU 热点

4.1 查看目标进程热点

sudo perf top -p ”$pid” -g

只观察用户态 CPU 周期:

sudo perf top -p ”$pid” -e cycles:u -g

如果需要稳定、可保存的结果,建议使用离线采样:

sudo perf record -F 99 -g -p ”$pid” -- sleep 30sudo perf report

4.2 常见热点解释

perf top主要显示正在 CPU 上运行的代码。线程如果大部分时间处于睡眠、I/O 等待或锁等待,可能不会形成明显的 CPU 热点,此时应继续使用 perf sched 或等待事件分析。

如果调用栈缺失,应检查:

  • 程序和依赖库是否保留符号。
  • 是否可以使用 frame pointer。
  • 当前系统是否支持 DWARF 调用栈采样。
  • 可执行文件、动态库和调试符号是否与运行版本一致。

5. 使用 perf sched 分析调度延迟

5.1 采集调度事件

sudo perf sched record -p ”$pid” -- sleep 30

部分旧版本不支持按 PID 过滤,可以采集全系统后再根据线程名和 PID 分析:

sudo perf sched record -a -- sleep 30

5.2 查看统计结果

sudo perf sched latencysudo perf sched timehistsudo perf sched map

6. 使用 perf lock 分析内核锁竞争

6.1 采集和查看内核锁事件

sudo perf lock record -p ”$pid” -- sleep 30sudo perf lock report

常见字段包括:

应优先检查 contended、wait total 和 wait max 较高的锁及其调用路径。

6.2 perf lock 的能力边界

perf lock主要分析Linux内核锁,不等同于完整的用户态 pthread_mutex 分析工具。用户态互斥锁在没有竞争时通常不会进入内核,因此不会被 perf lock 完整记录。

发生竞争的用户态锁通常会通过futex 进入内核,可以尝试采集 futex 系统调用:

sudo perf record -g \ -e syscalls:sys_enter_futex \ -e syscalls:sys_exit_futex \ -p ”$pid” -- sleep 30sudo perf report

先确认当前内核是否提供相应事件:

sudo perf list | grep -E 'lock|futex|sched'

如果 futex 等待明显,但调用栈无法定位到业务锁,还需要结合 eBPF、用户态探针或程序内的低开销锁统计。

 注意事项

  • Perf 采样本身存在开销,生产环境应控制采样频率和持续时间。
  • perf.data 可能包含进程符号、调用栈等运行信息,应按生产数据安全规范处理。
  • 大型 perf.data 文件应在分析完成后按要求归档或清理。
  • 硬件事件可能受虚拟机、容器权限、内核参数和 PMU 能力限制。
  • 不要只依据单个指标下结论,应结合业务吞吐、延迟和丢包结果判断。
  • perf top 看不到完整的 off-CPU 等待,perf lock 也不能覆盖所有用户态锁。
  • 本文命令中的参数应以目标服务器实际安装的 perf --help 输出为准。

最新文章

随机文章