在上一篇Linux x86_64进程内存空间布局中谈了两个不同参数下的进程运行时内存空间宏观的分布。也许你会注意到这样一个细节,在每个进程的stack以上的地址中,有一段动态变化的映射地址段,比如下面这个进程,映射到vdso。
如果我们用ldd看相应的程序,会发现vdso在磁盘上没有对应的so文件。
不记得曾经在哪里看到大概这样一个问题:
getpid,gettimeofday是不是系统调用?
其实这个问题的答案就和vDSO有关,杂x86_64和i386上,getpid是系统调用,而gettimeofday不是。
vDSO全称是virtual dynamic shared object,是一种内核将一些本身应该是系统调用的直接映射到用户空间,这样对于一些使用比较频繁的系统调用,直接在用户空间调用可以节省开销。如果想详细了解,可以参考这篇文档
下面我们用一段程序验证下:
#include <stdio.h>
#include <sys/time.h>
#include <sys/syscall.h>
#include <unistd.h>
int main(int argc, char **argv)
{
struct timeval tv;
int ret;
if ((ret=gettimeofday(&tv, NULL))<0) {
fprintf(stderr, "gettimeofday call failed\n");
}else{
fprintf(stdout, "seconds:%ld\n", (long int)tv.tv_sec);
}
fprintf(stdout, "pid:%d\n", (int)getpid());
fprintf(stdout, "thread id:%d\n", (int)syscall(SYS_gettid));
return 0;
}
编译为可执行文件后,我们可以用strace来验证:
strace -o temp ./vdso
grep getpid temp
grep gettimeofday temp