如何查看一个流程进行了多少次上下文切换?


25

我想看看我的过程是否进行了很多上下文切换。我还想了解操纵任务组如何影响上下文切换的数量。


什么操作系统?什么版本的?什么内核?
Mikel

GNU / Linux 2.6.18
2012年

5
检查/proc/[pid]/status
凯文(Kevin)

Answers:


30

您可以在中查看有关流程的上下文切换的信息/proc/<pid>/status

$ pid=307
$ grep ctxt /proc/$pid/status
voluntary_ctxt_switches:        41
nonvoluntary_ctxt_switches:     16

要查看这些数字不断更新,请运行

$ # Update twice a second.
$ watch -n.5 grep ctxt /proc/$pid/status

要获取数字,请运行

$ grep ctxt /proc/$pid/status | awk '{ print $2 }'

我尝试了上面的watch命令,但输出仅为1(用于自愿和非自愿上下文切换)。我的Linux内核版本是2.6.39-400.214.4.el6uek.x86_64。输出取决于linux版本吗?
安迪·杜弗雷斯

请在此处粘贴您的输出。

它与应答者中提到的相同-“观看-n.5 grep ctxt / proc / 5647 / status”
Andy Dufresne

我必须使用procfs,但是在旧内核上/proc/.../status中没有值。有什么建议吗?
马西莫'18

12

pidstat(1)-报告Linux任务的统计信息。根据man pidstat它是如此简单pidstat -w …


我执行了“ watch -n0.5 pidstat -w -I -p 5876”命令,但输出为0(对于两个cswch / s nvcswch / s)。这个命令对Linux版本2.6.39-400.214.4.el6uek.x86_64有效吗?
安迪·杜弗雷斯

该命令应该可以正常工作。但要注意你使用它错了,因为当你不指定报告间隔“的任务统计上报以来系统启动(引导)的时间。”类似的vmstatiostat和其他人。因此,如果需要当前的统计信息而不是watch仅以一秒的间隔运行它。
poige

如果我不看,我如何看待数字不断更新?执行命令“ pidstat -w -I -p 5876 5”,该命令仅等待5秒钟,然后打印输出(再次为0)。它并没有像我期望的那样连续运行(我知道这与pidstat的手册页所说的linux.die.net/man/1/pidstat相矛盾)。我的操作系统是Oracle Linux Server 6.4。
安迪·杜弗雷斯

pidstat -w -l -p SELF 1是否对您有用?
poige

4

要获得整个过程运行的记录,可以使用带有该选项的GNU time实用程序(不要将其与bash内置函数混淆)-v。这是一个示例,其中删除了不相关的输出行:

$ `which time` -v ls
a.out  exception_finder.cpp  log.txt
    Command being timed: "ls"
               ...
    Voluntary context switches: 1
    Involuntary context switches: 2
               ...
    Exit status: 0

3

您可以使用sar -w。例如,,sar -w 1 3每1秒每秒报告一次上下文切换总数,共3次。


1
即使该命令可用,在许多系统上也不是“开箱即用”。您可以在答案中包括如何启用数据收集sar吗?
Anthon'5

2

将以下脚本写入文件(ctx.sh)。与ctx.sh <core>您一起将看到在给定核心上运行的所有进程,并且将突出显示更改的nv上下文开关。看到这一点,您将能够确定哪些是核心的竞争过程。

#!/bin/bash

if [[ $# -eq 0 ]]
then
   echo "Usage:"
   echo "$0 <core>"
   exit 1
fi

if [[ -z $2 ]]
then
   watch -d -n .2 $0 $1 nw
fi

ps -Leo lastcpu:1,tid,comm | grep "^$1 " | awk '{printf $3": ";system("cut -d\" \" -f3  /proc/"$2"/task/"$2"/schedstat 2>/dev/null")}' | sort -k 1 | column -t

1

请参阅man getrusage,它将使您查询自愿和非自愿上下文切换的数量。

struct rusage {
           struct timeval ru_utime; /* user CPU time used */
           struct timeval ru_stime; /* system CPU time used */
           long   ru_maxrss;        /* maximum resident set size */
           long   ru_ixrss;         /* integral shared memory size */
           long   ru_idrss;         /* integral unshared data size */
           long   ru_isrss;         /* integral unshared stack size */
           long   ru_minflt;        /* page reclaims (soft page faults) */
           long   ru_majflt;        /* page faults (hard page faults) */
           long   ru_nswap;         /* swaps */
           long   ru_inblock;       /* block input operations */
           long   ru_oublock;       /* block output operations */
           long   ru_msgsnd;        /* IPC messages sent */
           long   ru_msgrcv;        /* IPC messages received */
           long   ru_nsignals;      /* signals received */
           long   ru_nvcsw;         /* voluntary context switches */
           long   ru_nivcsw;        /* involuntary context switches */
};

您可以告诉它报告每个线程的信息,如下所示:

struct rusage usage;
getrusage( RUSAGE_THREAD, &usage );

只需在关键部分之前和之后两次调用它,然后查看usage.ru_nivcsw值是否增加。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.