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

时间:2013-04-17 14:55:40

标签: linux ubuntu-12.04 ntp

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()联机帮助页(准确无误) 并没有真正说太多。

早期的联机帮助页版本(耐用) http://manpages.ubuntu.com/manpages/hardy/man2/ntp_gettime.2.html声称它可能是纳秒或微秒,具体取决于STA_NANO在[{1}}返回的status字中是否设置了ntp_adjtime()位。

任何人都知道了吗?除此之外,ntp_gettime()ntp_adjtime()以及他们在12.04源中定义的所有内部函数在哪里?

1 个答案:

答案 0 :(得分:5)

ntp_gettimentp_adjtime都在C库中定义。在Linux和glibc上,ntp_adjtime只是adjtimex系统调用的包装器,而ntp_gettime使用相同的系统调用通过struct timex设置modes您可以在the glibc LXR浏览他们的定义。

系统调用implementation调用_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)或重启之前,该标志将在内核中保持未设置状态。

相关问题