GetTickCount未到49天提前归0翻转

问题遇到的现象和发生背景

程序运行环境:windows server 2012操作系统。
程序开发环境:C++、MFC、VS2010

通过日志发现,GetTickCount函数返回值,在没有达到49天左右时,提前(31天左右)发生了归0翻转。

遇到的现象

从日志记录中发现:
当返回值为2684354091时,

1秒内再次记录时,该值为0。

3秒后,该值为3296,并持续累积。

相关代码

日志记录部分的代码:

DWORD dwTick = GetTickCount();
CString strTick;
strTick.Format(" %u ", dwTick);
// 记录到日志文件
Log2File(strTick)

程序中依赖该时间戳的逻辑同样因提前翻转出现了问题。
时间点和现象与日志记录的翻转时间相符。

运行结果及详细报错内容
我的解答思路

反复检查过代码,
没有任何地方显性或隐性的将返回值转换成WORD、SHORT或int,都使用了DWORD类型。
怀疑:
windows server 2012操作系统是否有相关的事件能够触发GetTickCount返回值归0,比如休眠等?但用户程序始终是不间断的运行,所以不可能是操作系统重启

我想要达到的结果,如果你需要快速回答,请尝试 “付费悬赏”

请问去除操作系统重启的情况下,是什么原因导致GetTickCount返回值在未到达49天时,提前发生归0翻转

您可以使用 QueryPerformanceCounter 函数来替代 GetTickCount 函数,它返回的是高精度的时间戳。或者使用 timeGetTime() 函数返回类似的值。

另外,还可以考虑使用 std::chrono::high_resolution_clock 来获取高精度时间戳。

使用 QueryPerformanceCounter 函数来替代 GetTickCount 函数:

LARGE_INTEGER liTick;
QueryPerformanceCounter(&liTick);
CString strTick;
strTick.Format(" %llu ", liTick.QuadPart);
// 记录到日志文件
Log2File(strTick);

使用 std::chrono::high_resolution_clock 来获取高精度时间戳:

auto time_now = std::chrono::high_resolution_clock::now();
auto duration = time_now.time_since_epoch();
unsigned long long int timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
CString strTick;
strTick.Format(" %llu ", timestamp);
// 记录到日志文件
Log2File(strTick);
 使用 std::chrono::high_resolution_clock 需要加上<chrono>头文件 

望采纳

很可能是数据超出范围了,将代码strTick.Format(" %u ", dwTick); 改为 strTick.Format(" %lu ", dwTick);

GetTickCount()函数返回当前系统的滴答数(tick count),滴答数是指系统启动以来的毫秒数。但是 GetTickCount() 函数的返回值是一个 DWORD 类型,最大值为 4,294,967,295,达到这个值后会发生归0。因此,它的最大值达到 49.7 天左右,如果系统运行时间超过这个值,就会发生归0翻转。

如果你的程序始终是不间断的运行,那么你可能要考虑更换其他时间函数来获取当前时间,如 GetTickCount64() 或 QueryPerformanceCounter() 等。

另外,请确保你的程序确实是始终不间断运行,这个问题可能是由于程序在睡眠、休眠或其他原因导致程序暂停运行而导致的。

现在电脑都是64位,可以改成 GetTickCount64(),不用纠结

GetTickCount函数返回值归0翻转的原因是它在系统启动后开始计时,并且返回的是以毫秒为单位的时间间隔,但它的计时范围是有限的,在大约49.7天后就会溢出,导致值归零。由于你这程序没有做任何转换和重置操作,所以在溢出之前就会发现这种现象。
仅供参考,望采纳,谢谢。