ntp_gettime()实际上是否返回纳秒精度?

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 ,因为tv_usec值,如果它确实是微秒计数,不应该大于ntp_gettime()上面显示的结果让我觉得ntp_gettime()实际上是返回纳秒精度。

http://manpages.ubuntu.com/manpages/precise/man2/ntp_gettime.2freebsd.html中的ntp_gettime()页(确切地说)并没有太多的说明。

较早版本的manpage版本(对于hardy) http://manpages.ubuntu.com/manpages/hardy/man2/ntp_gettime.2.html声称它可能是纳秒或微秒,这取决于是否在返回的status字中设置了STA_NANO位通过ntp_adjtime()

任何人都明确知道? 那么, ntp_gettime()ntp_adjtime()以及在12.04源代码中定义的所有内部函数在哪里?

ntp_gettimentp_adjtime都在C库中定义。 在Linux和glibc上, ntp_adjtime仅仅是adjtimex系统调用的一个包装器, ntp_gettime通过传递一个struct timex来将modes设置为0来使用相同的系统调用。您可以在glibc LXR中浏览它们的定义。

系统调用实现调用_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设置,直到你重置它(使用ADJ_NANO )或重启。