分析进程、线程、函数的 CPU 占用,是一个从宏观到微观逐层下钻的过程。核心思路是:先用轻量工具定位到"哪个进程"和"哪个线程"异常,再用
perf深入到"哪个函数"在消耗 CPU。第一步:定位高 CPU 进程
先用系统级工具找出嫌疑进程,这是最快的一步。
top:最直接。运行top后,默认按 CPU 使用率排序(或按Shift+P),看%CPU列最高的进程,记下其 PID 。ps:适合非交互式快照。命令ps -eo pid,cmd,%cpu --sort=-%cpu | head可以直接列出 CPU 占用最高的几个进程 。第二步:定位进程内的异常线程
现代 C++ 程序多为多线程,进程 CPU 高往往是其中某个线程在"忙等"或死循环。需要把线程揪出来。
top -H -p <PID>:这是最常用的方法。加上-H参数后,top会显示该进程内所有线程的 CPU 占用情况。找到%CPU高的线程,记下其 TID(线程 ID,通常与 PID 显示在同一列)。ps -L:静态查看线程。ps -p <PID> -L -o pid,tid,cmd,%cpu可以列出指定进程内各线程的 CPU 占用 。pidstat -t -p <PID> 1:如果需要持续监控线程级的 CPU 变化,pidstat输出更规整,适合观察波动 。第三步:下钻到函数级热点
拿到高 CPU 的线程 TID 后,就可以用
perf来回答"这个线程到底在跑什么代码"。
实时观察(快速确认)如果只想快速看一眼函数级的热点,可以直接用
perf top盯着那个线程:
bash
sudo perf top -t <TID>
这会实时显示该线程当前正在执行的函数及其占用比例。如果看到某个函数(比如
hot_mix)排在最前面,基本就锁定了目标 。
采样分析(精确定位与留存)如果要生成报告或进一步分析调用栈,用
perf record采样一段时间,再用perf report查看:
bash
# 对特定线程采样 30 秒,-g 记录调用栈
sudo perf record -t <TID> -g -- sleep 30
# 查看报告
sudo perf report
在
perf report界面里,你会看到按 Overhead(开销占比)排序的函数列表,按Enter可以展开看调用链,确认是哪个父函数调用了这个热点函数 。
关键提示 :编译时务必加上-g选项保留调试符号,并建议加上-fno-omit-frame-pointer以便perf能正确回溯调用栈,否则报告里可能只能看到一串地址或系统库函数,看不到你自己的代码 。总结流程
top→ 找到高 CPU 的 PID。top -H -p PID→ 找到高 CPU 的 TID。perf record -t TID -g+perf report→ 找到高 CPU 的 函数名。