mr.*_*tic 11

Linux 内核系统调用 API 是主要的 API(虽然隐藏在 libc 下,很少被程序员直接使用),并且大多数标准 IPC 机制严重偏向于一切都是文件的方法,这在此处消除了它们,因为它们最终需要读取/编写(以及更多)调用。

但是,在大多数平台上(如果您排除所有系统调用以到达那里)有一种方法:VDSO。这是一种机制,内核将一个(或多个)稍微神奇的页面映射到每个进程(通常以 ELF .so 的形式)。您可以linux-vdso.so使用ldd或将其视为或类似/proc/PID/maps。这是内核和用户进程之间有效的内存映射 IPC(尽管在其当前实现中是单向的)。

它通常用于加速系统调用,最初实现 ( linux-gate.so) 以解决 x86 性能问题,但它也可能包含内核数据和访问函数。调用喜欢getcpu()gettimeofday()可能使用这些,而不是进行实际的系统调用和内核上下文切换。这些优化调用的可用性由 glibc 启动代码检测并启用(取决于平台可用性)。当前的实现包含一个(只读)共享内核变量页面,称为“VVAR”页面,可以直接读取。

您可以通过检查 的输出来检查这一点,strace -e trace=clock_gettime date以查看您的date命令是否进行了任何clock_gettime()系统调用,而 VDSO 则不会(时间将由 VDSO 页面中的函数从 VVARS 页面读取,请参阅 参考资料arch/x86/vdso/vclock_gettime.c)。

这里有一个有用的技术摘要:http : //blog.tinola.com/?e=5更详细的教程:http : //www.linuxjournal.com/content/creating-vdso-colonels-other-chicken和手册页:http : //man7.org/linux/man-pages/man7/vdso.7.html


der*_*ert 9

不。

简单的反例,这将与内核交互:

int main() {
    volatile char *silly = 0;
    *silly = 'a';
}
Run Code Online (Sandbox Code Playgroud)

这将调用内核的页面错误处理程序,最终导致您的进程得到一个SIGSEGV(假设编译器没有“优化”该代码来做一些明显的事情,因为这是 C 标准的未定义行为,请确保编译与-O0)

  • 将`silly`作为全局变量并使其自身也变得易失性,没有理智的编译器会对其进行优化,因为它无法知道`silly`在链接过程中是否会被映射到内存映射的I/O区域,在这种情况下读取愚蠢的可能无法恢复先前存储在其中的“0”,但实际上可能会提供有效的地址。 (2认同)