Linux 進程由一個或多個執行緒組成。掌握查看線程數、線程狀態、線程級 CPU 佔用的方法,對於效能調優、死鎖排查、資源洩漏定位至關重要。本文介紹 4 種核心方法:top -H、ps 多種格式、/proc 檔案系統直讀、pidstat 統計工具,並解析進程/線程狀態碼含義。

top -H
# 或啟動後按 Shift+H 切換線程模式
PID (線程 ID, TID)、USER、PR/NI 優先級、%CPU (線程 CPU 佔用)、%MEM、COMMAND (顯示為進程名)。
ps -eLf # 標準輸出:UID PID PPID LWP C NLWP STIME TTY TIME CMD
# LWP = Light Weight Process = 線程 ID (TID)
# NLWP = Number of LWPs = 進程總線程數
ps -T -p # 顯示進程 PID 的所有線程 (SPID=LWP=TID)
ps -T -C # 按命令名過濾
# 自定義格式 (推薦腳本使用)
ps -o pid,tid,psr,pcpu,pmem,state,comm -p
# PID=進程ID, TID=線程ID, PSR=運行CPU核心, %CPU, %MEM, STATE=狀態, COMM=命令名
# 方法 A: ps + wc
ps -eLf | grep | wc -l
# 方法 B: 直接讀取 /proc (最快)
cat /proc//status | grep Threads
# 輸出: Threads: 42
/proc/ 目錄包含進程所有運行時資訊。
/proc//status :人類可讀狀態摘要 (含 Threads, VmSize/RSS, State, SigQ 等)。/proc//task/ :目錄,**每個線程一個子目錄**,名為 TID。ls /proc//task/ | wc -l 即線程數。/proc//task//stat :單線程詳細統計 (第 3 欄位 State)。/proc//stat :主線程統計,第 20 欄位 num_threads。| 碼 | 含義 | 說明 |
|---|---|---|
R | Running/Runnable | 正在運行或在運行隊列就緒 |
S | Sleeping (Interruptible) | 可中斷睡眠,等待事件 (I/O、信號、鎖) |
D | Disk Sleep (Uninterruptible) | 不可中斷睡眠 (通常為 I/O),收到信號不喚醒,**大量 D 狀態意味著 I/O 瓶頸** |
T | Stopped | 收到 SIGSTOP/SIGTSTP/SIGTTIN/SIGTTOU 暫停 (如 Ctrl+Z) |
t | Tracing Stop | 被除錯器 (strace/gdb) 暫停 |
Z | Zombie | 僵屍進程,已退出但父進程未 wait() 回收 |
X | Dead | 即將被銷毀 (極短暫) |
K | Wakekill | 接收致命信號喚醒中 |
W | Waking | 正在喚醒 (舊核心) |
P | Parked | 線程池閒置停放 (新核心) |
修飾符 (顯示在狀態碼前或後):
< 高優先級 (nice < 0)N 低優先級 (nice > 0)L 頁面鎖定在記憶體 (實時/IO)l 多線程 (使用 CLONE_THREAD, NPTL pthreads)+ 前台進程組範例:Rl+ = 運行中、多線程、前台進程組。
# 安裝
sudo apt install sysstat # 或 yum install sysstat
# 顯示所有進程的線程級 CPU 使用率 (每秒採樣 1 次,共 5 次)
pidstat -t -p ALL 1 5
# -t: 顯示線程 (-p ALL 所有進程)
# 輸出: UID TGID TID %usr %system %guest %CPU CPU Command
# TGID = 進程 ID (PID), TID = 線程 ID
# 顯示指定進程線程 I/O 統計
pidstat -d -t -p 1 3
# kB_rd/s, kB_wr/s, kB_ccwr/s (取消寫入)
# 顯示線程上下文切換統計
pidstat -w -t -p 1 3
# cswch/s (自願), nvcswch/s (非自願)
# 1. 找出高 CPU 線程 TID (十進位)
top -H -p # 或 pidstat -t -p 1 1
# 2. 轉換為十六進位
printf "%x\n"
# 例如 TID=12345 -> 0x3039
# 3. 獲取 Java 線程堆棧 (jstack)
jstack > threaddump.txt
# 4. 在堆棧中搜尋 nid=0x3039
grep -A 20 "nid=0x3039" threaddump.txt
# 定位到具體 Java 線程名、狀態、堆棧代碼行
查看 Linux 進程線程數與狀態的工具鏈分層:
top -H (互動式即時觀測) → ps -eLf / ps -T (靜態快照、腳本友好) → /proc/
掌握 **State 狀態碼 (R/S/D/T/Z/l/+)** 含義,能快速判斷線程是計算密集 (R)、I/O 等待 (D)、鎖競爭 (S/D)、已停止 (T) 或洩漏 (Z)。結合 jstack/perf/bpftrace 可深入定位代碼熱點。