为何Windows下steady_clock::now().time_since_epoch().count()返回重启后时长?
Windows下std::chrono::steady_clock的time_since_epoch()返回值不符合预期的原因
测试代码
#include <chrono> #include <iostream> int main(void) { const auto p1 = std::chrono::system_clock::now(); const auto p2 = std::chrono::steady_clock::now(); std::cout << "system_clock seconds since epoch: " << std::chrono::duration_cast<std::chrono::seconds>( p1.time_since_epoch()).count() << '\n'; std::cout << "steady_clock seconds since epoch: " << std::chrono::duration_cast<std::chrono::seconds>( p2.time_since_epoch()).count() << '\n'; return 0; }
运行输出
system_clock seconds since epoch: 1690157550 steady_clock seconds since epoch: 434342
原因解释
这是因为C++标准对steady_clock的定义仅要求它是单调递增的时钟(不会因系统时间调整而回退),并未强制规定其time_since_epoch()必须返回自Unix纪元(1970-01-01 00:00:00 UTC)起的时长。
在Windows平台上,steady_clock底层基于QueryPerformanceCounter(QPC)实现,这个计数器的起始点是系统启动后的某个基准时间,所以调用time_since_epoch()得到的是系统重启后的运行时长,而非自纪元以来的时间。
而system_clock的设计目标就是关联系统实时时间,因此它的time_since_epoch()才会返回符合预期的纪元时间,但代价是它可能会因系统时间调整(如NTP同步、手动修改时间)出现跳变。
替代方案
如果需要兼具单调性和纪元时间的特性,可以在程序启动时记录两者的差值:
#include <chrono> #include <iostream> int main(void) { const auto sys_start = std::chrono::system_clock::now(); const auto steady_start = std::chrono::steady_clock::now(); // 后续任意时刻 const auto current_steady = std::chrono::steady_clock::now(); const auto elapsed_steady = current_steady - steady_start; const auto current_sys = sys_start + elapsed_steady; std::cout << "Monotonic epoch time in seconds: " << std::chrono::duration_cast<std::chrono::seconds>( current_sys.time_since_epoch()).count() << '\n'; return 0; }
这样计算出的时间既保留了steady_clock的单调性,又能得到与纪元时间对齐的结果。
内容的提问来源于stack exchange,提问作者dmedine
相关产品推荐
相关产品推荐

