如何停止在Linux上倒退的时间?

下面是我写的一个小testing,用来validation时间确实只能在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; } 

testing失败,结果。

  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. 

VirtualBox Bug Tracker存在一个开放的问题 。 他们链接到一个博客文章,说明为什么你不应该使用gettimeofday()来衡量时间的流逝:

正确测量时间的最便携的方法似乎是clock_gettime(CLOCK_MONOTONIC,…)

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

大多数机器上的机器定时器只有15个左右的精度(甚至是本地代码)。 时间倒退是奇怪的,但是你真的不能依赖那个级别(1 usec)。 (还要注意:精度和准确度是有区别的;大多数定时器的精度比精度差)。 虚拟机的使用可能会加剧这一点。

更新:错字

这不是它倒退了。 最好是说它没有报告正确的时间。 这是因为计算机在没有专门的时间子系统的帮助下,不能在一毫秒内非常准确地报告时间。

精度将随着硬件,操作系统甚至电源而变化。 这里是一个初学者的文章 。 有点旧,但很好地传达了这个想法。

时间不应该在真实的硬件上倒退; 在VM上你的里程可能会有所不同。

无论如何,你的应用程序可能不应该认为时间不会倒退很少(可能是1秒)。

是的,clock_gettime是好的,但即使是在故障硬件(或虚拟机,如你的例子)的情况下可能会倒退。

我看到一个硬件错误使时间倒退(尽管偶尔),这是一个非常奇怪的问题的原因。

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