time()和gettimeofday()返回不同的秒数 [英] time() and gettimeofday() return different seconds

查看:593
本文介绍了time()和gettimeofday()返回不同的秒数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我测试过的两个系统(一台32位Ubuntu 12.04服务器和一台64位Ubuntu 13.10 VM)上,这是自 gettimeofday().

On the two systems I've tested (a 32-bit Ubuntu 12.04 server and a 64-bit Ubuntu 13.10 VM), the seconds since the epoch given by time() may differ from gettimeofday()'s.

具体来说,尽管我在调用gettimeofday()之后调用time() ,但是time()返回的值有时小于 gettimeofday().

Specifically, though I call time() after calling gettimeofday(), the value returned by time() is sometimes less than the tv_sec value returned by gettimeofday().

这显然是在时钟翻转到新的秒之后发生的.

This apparently occurs just after the clock rolls over to a new second.

这导致我的某些代码中的错误,它们期望time()和gettimeofday()的秒数可以互换.

This caused bugs in some of my code that expected time()'s and gettimeofday()'s seconds to be interchangeable.

演示此问题的示例代码:

Sample code demonstrating this problem:

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

int main()
{
  time_t start = time(NULL);
  int same = 0;
  int different = 0;
  int max_usec = 0;
  while (1) {
    time_t t;
    struct timeval tv;
    gettimeofday(&tv, NULL);
    t = time(NULL);
    if (t < tv.tv_sec) {
      different++;
      if (tv.tv_usec > max_usec) {
        max_usec = tv.tv_usec;
      }
    } else {
      same++;
    }
    if (t > start + 5) {
      break;
    }
  }
  printf("Same:      %i\n", same);
  printf("Different: %i\n", different);
  printf("Largest difference seen at %i\n", max_usec);
}

请注意,我是在第二次调用time(),并且只在它的值比gettimeofday()小于 时才抱怨.

Note that I'm calling time() second and only complaining if its value is less than gettimeofday()'s.

示例输出:

Same:      33282836
Different: 177076
Largest difference seen at 5844

即,这两个值是3300万次相同,它们是17.7万次,并且在新秒的5844微秒内始终是不同的.

I.e., the two values were the same 33 million times, they were different 177k times, and they were always different within 5844 microseconds of a new second.

这是一个已知问题吗?是什么原因造成的?

Is this a known issue? What causes this?

推荐答案

两个调用均以内核syscall的形式实现.这两个函数最终都会读取 ,它们都引用同一个实例.但是它们的处理方式有所不同:

Both calls are implemented as kernel syscalls. Both functions end up reading a struct timekeeper, both refer to the very same instance. But they differ in what they do with it:

使用 get_seconds() 函数,这是它的快捷方式:

uses the get_seconds() function, which is a shortcut to this:

struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;

它只返回xktime_sec.

gettimeofday()使用do_gettimeofday()(通过getnstimeofday)读取两个字段xktime_secxktime_nsec(通过

gettimeofday() on the other hand uses do_gettimeofday() (via getnstimeofday) which reads both fields xktime_sec as well as xktime_nsec (via timekeeping_get_ns). Here it might happen that xktime_nsec holds more nanoseconds than a second. This potential extra time is used to increase the tv_sec field by calling the function timespec_add_ns() which does this:

a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
a->tv_nsec = ns;

因此,tv_sec可能会比xktime_sec字段更大.这样就可以了:time()给你的东西和gettimeofday()给你的东西有点差异.

So, tv_sec might get bigger than the xktime_sec field was. And there you have it: a little difference in what time() gives you and what gettimeofday() gives you.

我今天在 fluxbox 中针对此问题进行了抗争,直到出现更好的解决方案,我对此表示赞同:

I fought against this issue in fluxbox today and until a better solution occurs I live with this:

uint64_t t_usec = gettimeofday_in_usecs(); // calcs usecs since epoch
time_t t = static_cast<time_t>(t_usec / 1000000L);

这篇关于time()和gettimeofday()返回不同的秒数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆