如何在Linux上停止时间倒流?

发布于 2024-10-14 10:59:05 字数 1270 浏览 5 评论 0原文

这是我编写的一个小测试,用于验证时间确实只在 Linux 中向前运行。

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

bool timeGoesForwardTest2()
{
   timeval tv1, tv2;   
   double startTime = getTimeSeconds();  // my function

   while ( getTimeSeconds() - startTime < 5 )
   {
      gettimeofday( &tv1, NULL );  
      gettimeofday( &tv2, NULL );  

      if ( tv2.tv_usec == tv1.tv_usec &&
           tv2.tv_sec == tv1.tv_sec )
      {
         continue;  // Equal times are allowed.
      }

      // tv2 should be greater than tv1
      if ( !( tv2.tv_usec>tv1.tv_usec ||
              tv2.tv_sec-1 == tv1.tv_sec ) )
      {
         printf( "tv1: %d %d\n", int( tv1.tv_sec ), int( tv1.tv_usec ) );
         printf( "tv2: %d %d\n", int( tv2.tv_sec ), int( tv2.tv_usec ) );
         return false;
      }         
   }
   return true;
}

结果测试失败。

 tv1: 1296011067 632550
 tv2: 1296011067 632549

嗯……

为什么会发生这种情况?

这是我的设置:

Linux version 2.6.35-22-generic (buildd@rothera) (gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu4) ) #33-Ubuntu SMP Sun Sep 19 20:34:50 UTC 2010 (Ubuntu 2.6.35-22.33-generic 2.6.35.4)
... running inside VirtualBox 3.2.12, in Windows 7.

Here's a little test I've written to verify that time does indeed only run forwards in Linux.

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

bool timeGoesForwardTest2()
{
   timeval tv1, tv2;   
   double startTime = getTimeSeconds();  // my function

   while ( getTimeSeconds() - startTime < 5 )
   {
      gettimeofday( &tv1, NULL );  
      gettimeofday( &tv2, NULL );  

      if ( tv2.tv_usec == tv1.tv_usec &&
           tv2.tv_sec == tv1.tv_sec )
      {
         continue;  // Equal times are allowed.
      }

      // tv2 should be greater than tv1
      if ( !( tv2.tv_usec>tv1.tv_usec ||
              tv2.tv_sec-1 == tv1.tv_sec ) )
      {
         printf( "tv1: %d %d\n", int( tv1.tv_sec ), int( tv1.tv_usec ) );
         printf( "tv2: %d %d\n", int( tv2.tv_sec ), int( tv2.tv_usec ) );
         return false;
      }         
   }
   return true;
}

Test fails with the result.

 tv1: 1296011067 632550
 tv2: 1296011067 632549

ummm....

Why does this happen?

Here's my setup:

Linux version 2.6.35-22-generic (buildd@rothera) (gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu4) ) #33-Ubuntu SMP Sun Sep 19 20:34:50 UTC 2010 (Ubuntu 2.6.35-22.33-generic 2.6.35.4)
... running inside VirtualBox 3.2.12, in Windows 7.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

清音悠歌 2024-10-21 10:59:05

gettimeofday() 不保证是单调的。如果您需要保证,请使用clock_gettime(CLOCK_MONOTONIC)

gettimeofday() is not guaranteed to be monotonic. Use clock_gettime(CLOCK_MONOTONIC) if you need that guarantee.

一个人的夜不怕黑 2024-10-21 10:59:05

VirtualBox Bug Tracker 上有一个未解决的问题。他们链接到一篇博客文章,说明为什么 你不应该使用 gettimeofday() 来测量时间的流逝:

最便携的时间测量方式
正确似乎是
Clock_gettime(CLOCK_MONOTONIC, ...)

There is an open issue at the VirtualBox Bug Tracker. They link to a blog post stating why you shouldn't use gettimeofday() to measure the passage of time:

The most portable way to measure time
correctly seems to be
clock_gettime(CLOCK_MONOTONIC, ...)

潜移默化 2024-10-21 10:59:05

大多数机器上的机器定时器只有大约 15 usec 精度(即使对于本机代码也是如此)。时间“倒退”很奇怪,但无论如何你真的不能依赖那个级别(1 usec)。 (另请注意:精度和准确度之间存在差异;大多数计时器的准确度比其精度差)。使用虚拟机也可能会加剧这种情况。

更新:错别字

Machine timers on most machines only have about 15 usec precision (even to native code). Time going 'backward' is odd, but you really can't rely on that level (1 usec) anyway. (Also note: there is a difference between precision and accuracy; the accuracy of most timers is worse than its precision). The use of a virtual machine may aggravate this as well.

Update: Typo

段念尘 2024-10-21 10:59:05

并不是说它在倒退。最好说它没有报告正确的时间。这是因为,如果没有专用计时子系统的帮助,计算机根本无法以单毫秒间隔非常准确地报告时间。

精度会因硬件、操作系统甚至电源的不同而有所不同。这是一篇针对初学者的文章。有点旧,但很好地传达了这个想法。

It's not that it's running backwards. It'd be better to say that it is not reporting the correct time. This is because computers, without the aid of a dedicated timing subsystem, simply are not capable of reporting time very accurately in single millisecond intervals.

The precision will vary with hardware, the OS and even the power supply. Here is an article for starters. A bit old but communicates the idea nicely.

硬不硬你别怂 2024-10-21 10:59:05

在真实的硬件上时间不应该倒流;在虚拟机上,您的里程可能会有所不同。

无论如何,您的应用程序可能不应该假设时间不会向后运行很小的量(想想,也许是 1 秒)。

是的,clock_gettime 很好,但即使在硬件(或虚拟机,如您的示例中)出现故障的情况下,也可能会向后运行。

我见过一个硬件错误使时间倒退(尽管非常偶然),这是一些非常特殊问题的原因。

特别是,当时间倒退时,任何涉及比较文件时间戳的事情都会出错。

Time should not run backwards on real hardware; on a VM your mileage may vary.

In any case, your application should probably not assume that time doesn't run backwards by a very small amount (think, maybe 1 second).

Yes, clock_gettime is good but even that could run backwards in the case of faulty hardware (or a VM, as in your example).

I have seen a hardware bug make time run backwards (albeit very occasionally), it was a cause of some very peculiar problems.

In particular, anything which involves comparing file timestamps will go wrong when time goes backwards.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文