4

Ubuntu 12.04 LTS 上的以下代码:

 #include <stdio.h>
 #include <sys/timex.h>
 #include <sys/time.h>

 int main(int argc, char **argv) 
 {
     struct timeval tv; 
     gettimeofday(&tv, NULL);

     struct ntptimeval ntptv;
     ntp_gettime(&ntptv);

     printf("gettimeofday: tv_sec = %ld, tv_usec = %ld\n", 
                tv.tv_sec, tv.tv_usec);
     printf("ntp_gettime:  tv_sec = %ld, tv_usec = %ld\n", 
                ntptv.time.tv_sec, ntptv.time.tv_usec);
 }

返回:

 gettimeofday: tv_sec = 1366209548, tv_usec = 137736
 ntp_gettime:  tv_sec = 1366209548, tv_usec = 137743081

这有点奇怪,因为该tv_usec值(如果确实是微秒计数)不应大于 1000000。上面显示的结果让我认为这ntp_gettime()实际上是返回纳秒精度。

http://manpages.ubuntu.com/manpages/precise/man2/ntp_gettime.2freebsd.html上的ntp_gettime()手册页(准确地说) 并没有说太多。

较早的手册页版本(适用于 hardy) http://manpages.ubuntu.com/manpages/hardy/man2/ntp_gettime.2.html声称它可能是纳秒或微秒,具体取决于该STA_NANO位是否在statusntp_adjtime().

有谁确切知道吗?除此之外,在 12.04 源代码中定义的ntp_gettime()ntp_adjtime()以及它们调用的所有各种内部函数在哪里?

4

1 回答 1

5

ntp_gettime并且ntp_adjtime都在 C 库中定义。在 Linux 和 glibc 上,ntp_adjtime它只是adjtimex系统调用的包装器,并通过将其传递给设置为 0ntp_gettime的方式使用相同的系统调用。您可以在glibc LXR中浏览它们的定义。struct timexmodes

系统调用实现调用_do_adjtimex调用getnstimeofday以获取时间(以纳秒为单位),然后将其交给__do_adjtimex。这是有趣的部分:

txc->time.tv_sec = ts->tv_sec;
txc->time.tv_usec = ts->tv_nsec;
if (!(time_status & STA_NANO))
        txc->time.tv_usec /= NSEC_PER_USEC;

因此,如果STA_NANO设置它只是将纳秒值放入tv_usec,这是您一直在经历的行为。如果要取消设置此标志,可以执行以下操作:

struct timex tmx;
tmx.modes = 0 | ADJ_MICRO;
ntp_adjtime(&tmx);

然后从中读取您的微秒值tmx.time.tv_usec。如果您想这样做,您必须使用 运行您的代码sudo,但请注意该标志将在内核中保持未设置,直到您重置它(使用ADJ_NANO)或重新启动。

于 2013-12-05T10:48:45.970 回答