系统调用
发起系统调用时的场景
查看系统调用
一个简单的 HelloWorld C程序发生了什么系统调用呢?
//hello.c
#include <stdio.h>
int main(void)
{
puts("hello world");
return 0;
}
可以通过strace命令来查看,执行
gcc -o hello hello.c
strace -o hello.log ./hello
其中关键的系统调用为write()

如果用Python进行上述同样的操作呢?
print("hello world")

可以看到,同样产生了write()这个关键的操作,需要注意的是,同样是打印一句hello world,python有六百多次系统调用。
其中1表示标准输出,即我们的屏幕,然后是输出的内容,以及内容的长度为12。
统计系统调用占比
也可以通过sar命令,来监控进程在用户模式和系统模式的时间比例
sar -P ALL 1 1
# -P cpu lists ALL表示全部
# 1 intervel 1代表间隔1s
# 1 count 1代表一次
结果如下:
其中 %user + %nice 为用户模式的时间占比,%system为内核模式占比,%idle为空闲占比。all一栏为所有CPU平均(sorry, 我只有1核…)
跑一个for循环来看看效果
//loop.c
int main(void)
{
for (;;)
;
}
执行结果:
可以看到,CPU上99%都是用户模式(因为采样周期的1s,如果多执行几次sar命令,会看到结果有些微差异,%nice可能为100%),可以推断出,这个循环是一直运行在用户模式的,当然,这也符合我们的认知。
如果我们一直在这个循环里加系统调用呢?改造一下程序
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
for (;;)
getppid();
}
执行结果:
可以看到,系统调用占了71%,用户模式下降到了29%
系统调用执行时间
上面是在CPU层面统计了运行时间占比,那如何知道进程的系统调用占比呢?比如我们现在需要知道二进制文件sleep3时间都花在哪里了,可以用strace -T。执行命令
strace -T -o sleep3.log ./sleep3
观察结果:

发现有3s的时间都花在系统调用nanosleep上,也就是sleep()上了,方便我们接下来的排查。
版权声明:本文为qq_26176515原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。