能,htop默认以进程聚合线程资源,需按H键开启线程视图才能看到各线程的TID、CPU%和MEM%,其中CPU%为单核占比,MEM%为进程共享。

htop 能直接看到线程级 CPU 和内存占用吗
能,但默认不显示——htop 默认以进程为单位聚合线程资源。要定位特定线程(比如某个 std::thread 或 pthread),必须开启线程视图模式,否则看到的只是进程总和,无法区分哪个线程在狂占 CPU。
操作很简单:htop 启动后按 H(大写 H)切换线程视图。此时所有线程会以 TID(线程 ID)为单位展开,父进程名后带 ─┬ 或 ─┘ 层级标识,PID 列实际显示的是 TID。
- 注意:Linux 下线程和进程共享同一个内核调度实体,
gettid()返回的值就是htop中显示的TID - 如果按
H后仍看不到预期线程,可能是该线程已退出,或程序未启用CLONE_THREAD(极少见,通常 C++11std::thread都满足) -
htop不显示线程名(如pthread_setname_np设置的名称),只显示可执行名 + 命令行参数片段
怎么把 C++ 线程 TID 和 htop 里的 TID 对上
关键在获取线程的真实内核 TID,不是 std::thread::id 或 pthread_self() 返回的用户态 handle。
在目标线程里加一段调试输出:
立即学习“C++免费学习笔记(深入)”;
#include <sys/syscall.h> #include <unistd.h> #include <iostream> long tid = syscall(SYS_gettid); std::cout << "My TID: " << tid << std::endl;
-
syscall(SYS_gettid)是唯一可靠方式;gettid()是 glibc 封装,某些旧系统可能未暴露 - 不要用
std::this_thread::get_id()—— 它是实现定义的,不能映射到htop的TID列 - 输出后立刻在
htop按F4输入TID数字过滤,或按F6选TID列排序,快速定位
为什么 htop 里看到的线程 CPU% 加起来远超 100%
这是正常现象,不是 bug。每个线程的 CPU% 是相对于单个逻辑核心的百分比,不是全局占比。
- 4 核 CPU 上,一个线程跑满单核显示
100%,4 个线程各占满一核,就显示 4 行100% - 若某线程显示
230%,说明它在最近采样周期内跨多个核心调度,且平均占用约 2.3 个逻辑核的算力 - 内存占用(
MEM%)才是进程内所有线程共享的,不会重复计算 - 想看整体负载,盯住顶部的 CPU 柱状图,或按
F2 → Display options → Show custom thread names(无实质作用,仅提示)
定位到线程后,下一步该查什么
htop 只是入口,它不告诉你线程在执行哪段代码。拿到高开销线程的 TID 后,必须结合其他工具深入:
- 用
cat /proc/<TID>/stack查当前内核栈(需 root 或相同 UID),看是否卡在锁、等待 I/O 或内核态 - 用
perf top -t <TID>实时看用户态热点函数(需编译时带-g,且无 strip) - 用
gdb -p <TID>附加后执行bt,确认调用栈——注意:C++ 异常栈、优化后的内联可能让结果难读 - 避免直接杀线程:
kill -9 <TID>可能破坏进程状态,优先用程序内信号或条件变量控制
线程 TID 在进程生命周期内有效,但 htop 刷新间隔(默认 1.5s)可能错过瞬时峰值;若问题偶发,建议配合 perf record -e cpu-clock --call-graph dwarf -t <TID> 录制后再分析。


















