【问题标题】:Understanding gettimeofday system call了解 gettimeofday 系统调用
【发布时间】:2014-03-26 04:26:37
【问题描述】:

我需要使用 gettimeofday 来测量使用此功能的微秒分辨率的时间差异。

我知道这不是最好的功能,但我想了解原因。 在这个question AndrewStone 中说会有一个问题两次 是的,我不明白如果我们只是从纪元开始计算微秒,为什么会有问题。

如果我误解了这个人,时间是秒+微秒的值,我该如何解决这个问题?

【问题讨论】:

  • AndrewStone 只是不知道他在说什么。但是,如果您想避免由手动时钟调整或行为不良的 ntpd 引起的错误(一个好的 ntpd 总是会不断地进行调整,因此它们不会干扰任何事情),那么使用单调时钟来测量间隔是一个很好的做法。跨度>

标签: c++ c time clock system-calls


【解决方案1】:

gettimeofday 接受两个参数:

int gettimeofday(struct timeval *tv, struct timezone *tz);

根据手册页:

timezone 结构的使用已过时; tz 参数通常应指定为 NULL。

如果您这样做,它将仅返回自纪元以来的秒数和微秒数,即不涉及时区。在这方面,谁告诉你不同的说法是错误的。

但是,您仍然需要小心一点。虽然你不会看到这个提前或延迟一个小时,但我相信你会发现它会随着墙上时间的调整而提前和延迟,比如ntp。因此,两次调用之间经过的微秒数可能不是两个结果之间的差异(例如,如果ntp 正在推进或推迟时钟)。

更好的方法是将clock_gettime()CLOCK_REALTIMECLOCK_MONOTONIC 一起使用,具体取决于您要测量的具体内容(经过的时间或时钟的变化)。

编辑:您想要一个例程来减去两个 timeval 结构。这是一个:

int
timeval_subtract (struct timeval *result, struct timeval *x,
                  struct timeval *y)
{
  if (x->tv_usec < y->tv_usec)
    {
      int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
      y->tv_usec -= 1000000 * nsec;
      y->tv_sec += nsec;
    }

  if (x->tv_usec - y->tv_usec > 1000000)
    {
      int nsec = (x->tv_usec - y->tv_usec) / 1000000;
      y->tv_usec += 1000000 * nsec;
      y->tv_sec -= nsec;
    }

  result->tv_sec = x->tv_sec - y->tv_sec;
  result->tv_usec = x->tv_usec - y->tv_usec;

  return x->tv_sec < y->tv_sec;
}

与这里的类似:http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html

【讨论】:

  • 抱歉有点慢,但你是说 timeval 的每个成员都持有相同的值但分辨率不同,还是我应该将秒转换为微秒并添加它们?如果一个偶数从 31.12.14 23:59:59 开始并在 2015 年结束,是否没有潜在的问题?
  • 不,我没有说这两件事。 timeval 保存秒和微秒(显然,两个调用都相同),您需要编写一个小例程来从另一个中减去一个(我将在帖子中一秒钟内为您包括一个)。我已经告诉过你潜在的问题是什么(墙上时间可能会被 ntp 等扭曲)以及修复它们的正确方法(clock_gettime)。但是,如果您将tz 参数作为NULL 传递给gettimeofday,那么夏令时的更改不是问题。
  • 非常感谢。最后一件事,在年底没有错误计算时间的危险吗?
  • 在年底gettimeofday 的结果并没有什么特别之处,除了传统上这是在引入/删除闰秒时,这将属于危险如上所述的“调整”。
猜你喜欢
  • 2023-04-09
  • 2017-04-19
  • 1970-01-01
  • 2023-03-18
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
相关资源
最近更新 更多