如何在Linux上停止时间倒流?
这是我编写的一个小测试,用于验证时间确实只在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
gettimeofday()
不保证是单调的。如果您需要保证,请使用clock_gettime(CLOCK_MONOTONIC)
。gettimeofday()
is not guaranteed to be monotonic. Useclock_gettime(CLOCK_MONOTONIC)
if you need that guarantee.VirtualBox Bug Tracker 上有一个未解决的问题。他们链接到一篇博客文章,说明为什么 你不应该使用 gettimeofday() 来测量时间的流逝:
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:
大多数机器上的机器定时器只有大约 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
并不是说它在倒退。最好说它没有报告正确的时间。这是因为,如果没有专用计时子系统的帮助,计算机根本无法以单毫秒间隔非常准确地报告时间。
精度会因硬件、操作系统甚至电源的不同而有所不同。这是一篇针对初学者的文章。有点旧,但很好地传达了这个想法。
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.
在真实的硬件上时间不应该倒流;在虚拟机上,您的里程可能会有所不同。
无论如何,您的应用程序可能不应该假设时间不会向后运行很小的量(想想,也许是 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.