以下是一個改進的命令,可以列出所有線程數大于200的進程及其PID和線程數:
find /proc -maxdepth 1 -type d -regex '/proc/[0-9]+' -exec sh -c 'for pid_dir dopid=$(basename "$pid_dir")if [ -f "$pid_dir/status" ]; thenthreads=$(awk "/Threads/ {print \$2}" "$pid_dir/status" 2>/dev/null)if [ -n "$threads" ] && [ "$threads" -gt 200 ]; thenecho "PID: $pid, Threads: $threads"fifidone
' sh {} +
命令詳解:
-
查找所有PID目錄:
find /proc -maxdepth 1 -type d -regex '/proc/[0-9]+'
-maxdepth 1
:只搜索/proc頂層目錄-type d
:只匹配目錄-regex
:正則匹配純數字PID目錄
-
高效處理目錄:
-exec sh -c '...' sh {} +
- 使用
find -exec +
批量處理目錄,比逐個處理更高效 - 避免
for i in $(ls)
可能導致的空格問題
- 使用
-
提取線程數:
threads=$(awk "/Threads/ {print \$2}" "$pid_dir/status" 2>/dev/null)
- 使用
awk
精確提取Threads行的第二個字段 2>/dev/null
忽略權限錯誤或已終止進程
- 使用
-
條件過濾:
if [ -n "$threads" ] && [ "$threads" -gt 200 ]; then
-n "$threads"
:確保成功獲取線程數-gt 200
:篩選線程數大于200的進程
輸出示例:
PID: 1234, Threads: 250
PID: 5678, Threads: 312
PID: 9012, Threads: 280
優化版本(單行命令):
find /proc -maxdepth 1 -name '[0-9]*' -type d -exec awk -F: '/^Pid|^Threads/ {pid=$2; getline; if($2>200) printf "PID: %d, Threads: %d\n", pid, $2}' {}/status \; 2>/dev/null
關鍵改進:
- 避免解析
ls
輸出:直接使用find
匹配目錄,更安全可靠 - 高效批量處理:使用
find -exec +
減少子進程創建 - 錯誤處理:忽略無法訪問的進程目錄
- 精確匹配:確保只處理有效進程狀態文件
- 完整輸出:同時顯示PID和線程數
注意:某些系統進程可能無法訪問(權限問題),這些會被自動忽略。
寫在最后:
springboot內嵌兩種Web服務器,Undertow和Tomcat,業務正常情況下線程數都不會大于200太多,如果大太多,那么有可能程序存在線程泄露的問題,更進一步可能會導致業務不可用