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

ckl*_*lin 4 linux ntp ubuntu-12.04

在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);
 }
Run Code Online (Sandbox Code Playgroud)

返回:

 gettimeofday: tv_sec = 1366209548, tv_usec = 137736
 ntp_gettime:  tv_sec = 1366209548, tv_usec = 137743081
Run Code Online (Sandbox Code Playgroud)

这有点奇怪,因为该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位是status由返回的字设置的ntp_adjtime()

有人确切知道吗?的短,在哪里ntp_gettime()ntp_adjtime()以及在12.04源定义的所有他们所谓的各种内部功能?

Sam*_*ter 5

ntp_gettimentp_adjtime都在C库中定义。在Linux和glibc,ntp_adjtime是只为一个包装adjtimex系统调用,并ntp_gettime通过传递一个使用相同的系统调用struct timexmodes设置为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;
Run Code Online (Sandbox Code Playgroud)

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

struct timex tmx;
tmx.modes = 0 | ADJ_MICRO;
ntp_adjtime(&tmx);
Run Code Online (Sandbox Code Playgroud)

然后从读取您的微秒值tmx.time.tv_usec。如果要执行此操作,则必须使用来运行代码sudo,但是请注意,在重置(使用ADJ_NANO)或重新启动之前,该标志在内核中将保持未设置状态。