为什么 Linux 工具不使用系统调用来获取当前时间?

Oth*_*eus 5 linux clock syscalls

我真的很想理解为什么我们的来宾 VM 没有“像他们应该那样”使用 kvm-clock 驱动程序。他们正在运行 RHEL 7.2、glibc-2.17、kern 3.10.0。诸如date和 之类的程序perl -e 'print time'获取当前时间,但无需进行系统调用即可。这证实使用Strace和ltrace和通过用gdb和组件跟踪通过该旁路进一步证实syscall和转而执行一些指令来调用rtdscp

这是 glibc 作者的优化尝试吗?有什么方法可以禁用它并强制 glibc 调用进行系统调用(缺少 LD_PRELOAD hacks)?

更新2016-10-14:

在查看了最新的POSIX 草案后,部分答案很清楚:有一种方法可以从 CPU 请求时钟,但是 GNU glibc 错误地将这种实现强加给了它的用户。解决方法是直接调用系统调用。(嘘)

如果定义了 _POSIX_CPUTIME,则实现应支持通过调用 clock_getcpuclockid() 获得的时钟 ID 值,它表示给定进程的 CPU 时间时钟。实现还应支持特殊的clockid_t 值CLOCK_PROCESS_CPUTIME_ID,它表示调用clock_ () 或timer_ () 函数之一时调用进程的CPU 时间时钟。

鉴于用户可以 是否有任何真正的论据反对将 ifclock_id设置为CLOCK_REALTIME,则应该使用系统调用?

ilk*_*chu 12

我认为您没有看到系统调用发生的原因是一些 Linux 系统调用(尤其是那些与时间相关的调用,例如gettimeofday(2)time(2))通过vDSO进行了特殊实现,其中包含一些系统调用的一些优化实现:

“vDSO”(虚拟动态共享对象)是内核自动映射到所有用户空间应用程序地址空间的小型共享库。

内核提供了一些系统调用,用户空间代码最终会频繁使用,以至于这些调用可以支配整体性能。这是由于调用频率以及退出用户空间和进入内核导致的上下文切换开销。

现在,手册提到所需的信息只是放在内存中,以便进程可以直接访问它(毕竟当前时间并不是什么秘密)。我不知道确切的实现,只能猜测 CPU 的时间戳计数器在其中的作用。

因此,实际上并不是 glibc 进行优化,而是内核。它可以通过vdso=0内核命令行上设置来禁用,并且应该可以编译它。但是,我找不到是否可以在 glibc 端禁用它(至少在不修补库的情况下)。

在 SE上有很多关于这个问题的其他信息和来源。


你在问题中说:

在查看了最新的 POSIX 草案后,部分答案很清楚:有一种方法可以从 CPU 请求时钟,但是 GNU glibc 错误地将这种实现强加给了它的用户。

我认为这是一个相当大胆的声明。我没有看到任何“错误地强迫”用户做任何事情的证据,至少不会对他们不利。当前系统上运行的几乎每个 Linux 进程都使用 vDSO 实现,这意味着如果它不能正常工作,就会听到一些非常响亮的抱怨。你也说自己收到的时间是正确的。

您从clock_gettime手册中给出的引用似乎只提到调用必须支持由 返回的时钟 ID clock_getcpuclockid,而不是关于CLOCK_REALTIME或的行为的任何内容gettimeofday