wchan统计排序

对,问题在这里:

sort -t'|' -k1,1 -k2,2 -k4,4nr

这是按:

  1. COMMAND

  2. STAT

  3. 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/15bnx2i_thread

  • ksoftirqd/0 ~ ksoftirqd/Nksoftirqd

  • 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

这样最容易直接看出某个进程/线程组到底大量阻塞在哪里

posted on 2026-08-24 21:16  小镇-做题家  阅读(3)  评论(0)    收藏  举报

导航