wchan统计排序
对,问题在这里:
sort -t'|' -k1,1 -k2,2 -k4,4nr
这是按:
-
COMMAND -
STAT -
THREADS
排序。
所以 THREADS 只是在同一个 COMMAND + STAT 内部排序,不会让整个输出按 THREADS 从大到小排列。
如果你的要求是:
所有 COMMAND / STAT / WCHAN 按 THREADS 从大到小整体排序,同时相同 COMMAND 连续显示
直接改成:
sort -t'|' -k4,4nr -k1,1 -k2,2
不过还有一个问题:你后面的 awk 是按照 $1 != last 插入空行,因此 COMMAND 不一定严格按你想要的方式组织。
推荐完整版本
这个版本会:
-
bnx2i_thread/0~bnx2i_thread/15→bnx2i_thread -
ksoftirqd/0~ksoftirqd/N→ksoftirqd -
按
THREADS全局从大到小 -
相同 COMMAND 内继续按
STAT -
相同 COMMAND + STAT 内继续按
WCHAN -
输出空行区分 COMMAND
ps -eLo pid,tid,stat,wchan:40 --no-headers |
while read pid tid stat wchan; do
comm=$(cat /proc/$pid/comm 2>/dev/null)
[ -z "$comm" ] && continue
# xxx/数字 -> xxx
case "$comm" in
*/[0-9]*)
base="${comm%/*}"
suffix="${comm##*/}"
case "$suffix" in
''|*[!0-9]*)
;;
*)
comm="$base"
;;
esac
;;
esac
printf '%s|%s|%s\n' "$comm" "${stat:0:1}" "$wchan"
done |
awk -F'|' '
{
cnt[$1,$2,$3]++
}
END {
for (k in cnt) {
split(k,a,SUBSEP)
printf "%s|%s|%s|%d\n", a[1],a[2],a[3],cnt[k]
}
}' |
sort -t'|' -k4,4nr -k1,1 -k2,2 -k3,3 |
awk -F'|' '
BEGIN {
last=""
printf "%-40s %-5s %-40s %10s\n",
"COMMAND","STAT","WCHAN","THREADS"
printf "%-40s %-5s %-40s %10s\n",
"----------------------------------------",
"-----",
"----------------------------------------",
"----------"
}
{
if ($1 != last) {
if (last != "")
printf "\n"
last=$1
}
printf "%-40s %-5s %-40s %10d\n",
$1,$2,$3,$4
}'
但如果你的真正需求是“每个 COMMAND 内部按 THREADS 排序”
比如你想得到:
COMMAND STAT WCHAN THREADS
---------------------------------------- ----- ---------------------------------------- -------
tikv-server S futex_wait 128
S epoll_wait 96
S pthread_cond_wait 64
R - 32
bnx2i_thread S bnx2i_percpu_io_thread 15
ksoftirqd S smpboot_thread_fn 16
那么应该使用:
sort -t'|' -k1,1 -k4,4nr -k2,2 -k3,3
也就是:
COMMAND → THREADS降序 → STAT → WCHAN
两种排序的区别
| 排序命令 | 效果 |
|---|---|
-k1,1 -k2,2 -k4,4nr |
COMMAND → STAT → THREADS |
-k1,1 -k4,4nr -k2,2 |
COMMAND → THREADS → STAT |
-k4,4nr -k1,1 -k2,2 |
THREADS 全局降序 → COMMAND → STAT |
如果你是为了做 TiKV/MongoDB/Linux 内核线程分析,我建议用第二种:
sort -t'|' -k1,1 -k4,4nr -k2,2 -k3,3
这样最容易直接看出某个进程/线程组到底大量阻塞在哪里。
浙公网安备 33010602011771号