Windows下机器休眠时chrono::steady_clock计时不准确如何解决?
Windows平台排除休眠时间的计时器实现
在Windows平台,要实现类似macOS mach_absolute_time、排除系统休眠时长的计时器,可使用系统API QueryUnbiasedInterruptTime,该API返回系统启动后经过的时间,但会自动排除系统休眠、挂起的时间段,完全匹配你的需求。
直接使用API的示例代码
#include <windows.h> #include <iostream> int main() { ULONGLONG before, after; // 获取当前无偏中断时间(排除休眠) QueryUnbiasedInterruptTime(&before); Sleep(30000); // 模拟目标代码执行,期间系统休眠的时间不会被计入 QueryUnbiasedInterruptTime(&after); // 计算差值:返回值单位为100纳秒,转换为秒 double duration_seconds = (after - before) / 10000000.0; std::cout << "实际执行时长(排除休眠):" << duration_seconds << " 秒" << std::endl; return 0; }
封装为std::chrono兼容的时钟
如果你希望保持和原代码中std::chrono类似的使用风格,可以封装一个自定义时钟类型:
#include <windows.h> #include <chrono> #include <iostream> struct unbiased_clock { using rep = ULONGLONG; using period = std::ratio<1, 10000000>; // 对应100纳秒单位 using duration = std::chrono::duration<rep, period>; using time_point = std::chrono::time_point<unbiased_clock>; // 时钟是单调递增的 static constexpr bool is_steady = true; static time_point now() noexcept { ULONGLONG raw_time; QueryUnbiasedInterruptTime(&raw_time); return time_point(duration(raw_time)); } }; int main() { auto before = unbiased_clock::now(); Sleep(30000); auto after = unbiased_clock::now(); // 转换为秒输出 int duration = std::chrono::duration_cast<std::chrono::seconds>(after - before).count(); std::cout << duration << std::endl; return 0; }
关键说明
QueryUnbiasedInterruptTime从Windows Vista及以上版本开始支持,你的MSVC 19.29环境对应的系统(Windows 10/11)完全满足要求。- 该API返回的时间单调递增,不会受系统时间调整(如手动修改时间、NTP同步)的影响,同时自动排除系统休眠、挂起的时长。
- 与
std::chrono::steady_clock的区别:后者在Windows底层基于QueryPerformanceCounter,其计数在系统休眠时可能因硬件差异继续递增,而QueryUnbiasedInterruptTime是系统维护的无偏时间,明确排除休眠时段。
内容的提问来源于stack exchange,提问作者finalreq
相关产品推荐
相关产品推荐

