在Linux中监视系统CPU /系统调用

我有几个进程正在吃掉很多系统CPU时间(通过查看vmstat)。 有没有简单的方法来找出正在进行什么样的系统调用?

我知道有strace,但有一个更快,更简单的方法? 系统调用是否存在类似“顶部”的内容?

我认为与-c标志strace可能是我所知最接近的。 如果你还没有使用-c标志,试试这个:

 $ sudo strace -c -p 12345 

其中12345是相关stream程的进程ID(PID)。 请注意,对进程进行连接确实会增加额外的开销,因此在进行跟踪时,进程将会运行得更慢。

在运行了很长时间之后,要收集数据,请按Ctrl-C停止数据收集并输出结果。 它会产生这样的东西:

 % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 31.88 0.001738 145 12 futex 16.79 0.000915 11 80 tgkill 12.36 0.000674 34 20 read 9.76 0.000532 266 2 statfs 8.42 0.000459 13 35 time 4.38 0.000239 6 40 gettimeofday 3.65 0.000199 4 48 sigprocmask 2.94 0.000160 18 9 open 2.88 0.000157 12 13 stat64 1.32 0.000072 9 8 munmap 0.90 0.000049 6 8 mmap2 0.88 0.000048 3 14 7 sigreturn 0.79 0.000043 5 9 close 0.77 0.000042 4 10 rt_sigprocmask 0.64 0.000035 3 12 setitimer 0.55 0.000030 5 6 6 rt_sigsuspend 0.53 0.000029 4 8 fstat64 0.29 0.000016 8 2 setresuid32 0.13 0.000007 4 2 _llseek 0.09 0.000005 3 2 prctl 0.04 0.000002 2 1 geteuid32 ------ ----------- ----------- --------- --------- ---------------- 100.00 0.005451 341 13 total 

如您所见,这是应用程序所做的所有系统调用的细分,按总时间sorting,包括每个调用的平均时间和每个系统调用的调用次数。 如果您想对它们进行不同的sorting,请参阅strace的手册页,因为有几个选项。

也许可以尝试其中一个采样分析器,比如oprofile,或者更新的内核perf。 如果幸运的话,“perf top”可能会正确地告诉你你想要什么。 看到这里的一些例子

我倾向于使用strace开关的types是这样的。

strace -ffttT -p pid -o /tmp/strace.out

这个例子看起来像,

 19:35:57.485493 mprotect(0x7f35e7472000, 16384, PROT_READ) = 0 <0.000037> 19:35:57.485599 mprotect(0x7f35e7692000, 4096, PROT_READ) = 0 <0.000030> 19:35:57.485697 mprotect(0x7f35e78b7000, 4096, PROT_READ) = 0 <0.000030> 19:35:57.485782 munmap(0x7f35e7896000, 129588) = 0 <0.000037> 19:35:57.485875 set_tid_address(0x7f35e78949d0) = 10730 <0.000029> 19:35:57.485960 set_robust_list(0x7f35e78949e0, 0x18) = 0 <0.000024> 19:35:57.486048 futex(0x7fff8f58628c, FUTEX_WAKE_PRIVATE, 1) = 0 <0.000025> 19:35:57.486131 futex(0x7fff8f58628c, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1, NULL, 7f35e7894700) = -1 EAGAIN (Resource temporarily unavailable) <0.000024> 

您会看到系统调用右侧的时间差异,显示从一次系统调用转到另一次系统调用需要多less时间。

它会捕捉到系统调用之间的时间差异。 所以,当你看到一个系统调用与下一个系统调用有很大的差距时,那么它就会产生一些噪音。

另一种方法是用gcore把它堆成一团。 但是,这需要通过gdb导航一些经验。

但是,如果线程是内核线程,那么您不能对它进行strace或coredump。 在这种情况下,我们必须使用更复杂的东西。 在RHEL5内核中,我们使用oprofile。 在RHEL6中,我们使用perf。 我更喜欢perf opile。 Perf数据可以用类似graphics的格式收集,显示正在使用CPU的最大百分比的系统调用。

用testingperf,我看到这个。

 38.06% swapper [kernel.kallsyms] [k] mwait_idle_with_hints ↑ 29.45% swapper [kernel.kallsyms] [k] read_hpet 4.90% swapper [kernel.kallsyms] [k] acpi_os_read_port ▒ 4.74% swapper [kernel.kallsyms] [k] hpet_next_event 

它显示了CPU占用38%的时间的内核函数。 现在,我们可以检查函数,看看它在做什么以及它应该做什么。

举几个例子,这并不难。