唯一可靠方式是调用syscall(SYS_gettid)获取真实TID,再读取/proc/self/task/TID/stat(含状态码、utime/stime、CPU编号)和/proc/self/task/TID/status(含State、上下文切换数等),须检查文件是否存在,不可用/proc/self/threads或std::thread::id替代。

直接读/proc/self/task/<code>TID/stat和/proc/self/task/<code>TID/status就能拿到真实线程状态
Linux下没有“线程状态查询API”,std::thread::id或pthread_self()返回的都不是内核能识别的ID,没法用来拼路径。唯一可靠方式是:先用syscall(SYS_gettid)拿到当前线程的真实TID(类型pid_t),再拼出/proc/self/task/<code>TID/stat和/proc/self/task/<code>TID/status两个文件路径去读。
注意:/proc/self是符号链接,指向当前进程;/proc/self/task/下每个数字子目录名就是TID,不是std::thread::id转成整数的结果——那基本对不上。
-
/proc/self/task/<code>TID/stat里第3列是运行状态码(R/S/D/Z等),第14/15列是utime/stime(单位jiffies),第39列是最近调度所在的CPU编号 -
/proc/self/task/<code>TID/status里有更易读的字段:State:(对应stat里的状态码)、voluntary_ctxt_switches:、nonvoluntary_ctxt_switches:、StkSize:、StkGrow: - 读取前必须检查文件是否存在——线程可能已退出,
open()会返回ENOENT
别碰/proc/self/threads,它只告诉你有几个线程,不给任何状态
/proc/self/threads是个纯文本文件,每行一个线程名(其实是comm字段),内容类似main、worker,没有任何TID、状态、时间戳信息。它不能替代/proc/self/task/遍历——这是新手最常踩的坑。
真正要查状态,必须进/proc/self/task/目录用opendir()逐个读子目录名,再对每个数字目录做stat/status解析。
立即学习“C++免费学习笔记(深入)”;
-
/proc/self/task/下子目录名就是TID,可直接用strtol()转成pid_t - 不要试图用
std::thread::hardware_concurrency()或std::thread::id来猜TID——它们和内核线程ID完全无关 -
/proc/self/task/是虚拟文件系统,读取开销小,但仍是系统调用,频繁轮询(如
State字段含义要对照内核文档,不能凭经验猜
/proc/self/task/<code>TID/stat第3列是单字符状态码,/proc/self/task/<code>TID/status里State:行是带括号的描述(如State: S (sleeping))。两者等价,但后者更直观。
常见值包括:R(running or runnable)、S(interruptible sleep)、D(uninterruptible disk sleep)、Z(zombie)。其中S最常见,涵盖等待锁、条件变量、IO、sleep等所有主动阻塞场景。
-
D状态难被kill,通常意味着线程卡在底层驱动(如坏磁盘、NFS挂起),不是应用层问题 -
Z在线程已终止但父线程未wait()时出现,C++里对应std::thread对象析构前没join()或detach() - 状态是瞬时快照,不是持续区间——读到
S不代表线程“正在等锁”,只是采样那一刻它处于该状态
想看栈用量就盯StkGrow,但得确认内核版本支持
/proc/self/task/<code>TID/status里的StkGrow:字段表示该线程已实际使用的栈空间(单位KB),StkSize:是分配的总栈大小。这是目前Linux上最直接的线程栈监控方式。
但要注意:StkGrow在较老内核(cat /proc/self/status | grep Stk验证字段是否存在。
-
StkGrow按页统计,不是字节级精度,数值是近似值 - 主线程的栈信息在
/proc/self/status里,子线程必须进/proc/self/task/<code>TID/status - 如果线程栈爆了(SIGSEGV),
StkGrow不会体现异常,得结合core dump或ulimit -s排查
syscall(SYS_gettid)拿到的TID才能准确定位,跳过这步就等于在盲人摸象。


















