如果一个线程正在做这样的事情:
const DWORD interval = 20000;
DWORD ticks = GetTickCount();
while(true)
{
DoTasksThatTakeVariableTime();
if( GetTickCount() - ticks > interval )
{
DoIntervalTasks();
ticks = GetTickCount();
}
}最后,当值不适合DWORD时,ticks将自动换行。
我一直在和一个同事讨论这个问题。我们中的一个人相信,当回绕发生时,代码仍然会表现得“很好”,因为减法操作也会回绕。我们中的另一个人认为它并不总是有效的,特别是如果间隔很大的话。
谁是对的,为什么?
谢谢。
发布于 2009-04-07 23:05:46
来自the docs
将经过的时间存储为DWORD值。因此,如果系统连续运行49.7天,时间将接近于零。要避免此问题,请使用GetTickCount64。否则,在比较时间时检查是否有溢出情况。
但是,DWORD是未签名的-所以您应该没问题。0-“非常大的数字”=“小数字”(当然,假设你没有激活任何溢出检查)。我之前的编辑建议你会得到一个负数,但那是在我考虑到DWORD是无符号的之前。
但是,如果操作时间不到49.7天,您仍然会遇到问题。这对你来说可能不是问题;)
测试的一种方法是清除GetTickCount()方法,这样您就可以编写单元测试,显式地包装它。同样,如果你真的只是怀疑算术部分,你可以很容易地为此编写单元测试:)真的,数字来自系统时钟的事实几乎是无关紧要的,只要你知道它换行时的行为-这在文档中有规定。
发布于 2009-04-09 07:01:20
如果您想测试当GetTickCount()包装时发生了什么,您可以启用应用程序验证器的TimeRollOver测试。
来自Using Application Verifier Within Your Software Development Lifecycle
TimeRollOver强制GetTickCount和TimeGetTime API以比正常速度更快的速度转存。这允许应用程序更容易地测试它们对时间翻转的处理。
发布于 2009-06-04 02:13:58
我建议计算两个刻度之间的实际运行时间,而不是依靠编译器来为您处理:
const DWORD interval = 20000;
#define TICKS_DIFF(prev, cur) ((cur) >= (prev)) ? ((cur)-(prev)) : ((0xFFFFFFFF-(prev))+1+(cur))
DWORD ticks = GetTickCount();
while(true)
{
DoTasksThatTakeVariableTime();
DWORD curticks = GetTickCount();
if( TICKS_DIFF(ticks, curticks) > interval )
{
DoIntervalTasks();
ticks = GetTickCount();
}
}https://stackoverflow.com/questions/727918
复制相似问题