为什么 stable_clock::now().time_since_epoch().count() 返回 Windows 上重新启动后的时间?

dme*_*ine 4 c++ std c++-chrono

Windows 10 上的以下代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

system_clock seconds since epoch: 1690157550
steady_clock seconds since epoch: 434342
Run Code Online (Sandbox Code Playgroud)

因此,steady_clock即使我要求自纪元以来的时间,似乎也会计算自上次启动以来的时间。对我来说这是不正确的。自纪元以来,它并没有给我时间。

Sam*_*hik 7

作为一般要求,C++ 标准没有对所有时钟强加任何具体的纪元定义:

\n
\n

27.3 Cpp17时钟要求[time.clock.req]

\n

1时钟是由持续时间、时间点和用于获取当前时间点的函数 now() 组成的包。时钟\xe2\x80\x99s\ntime_point 的原点称为时钟\xe2\x80\x99s 纪元。

\n
\n

句号。一个特定的时钟有某种起源纪元,但它是什么,一般没有指定。它是为每个特定时钟指定的(如果有)。

\n

system_clock例如, 的起源明确给出为 Jan 1 1970 :

\n
\n

类 system_clock [time.clock.system]

\n

[ ... ]\nsystem_clock 类型的对象表示系统范围实时时钟的挂钟时间。sys_time 类型的对象测量自 1970-01-01 00:00:00 UTC 以来的时间,不包括闰秒。

\n
\n

没有给出这样的要求steady_clock。C++ 标准未指定起源或时代steady_clock。给你的唯一保证steady_clock就是永远不会减少。来自 C++ 标准:

\n
\n

类 stable_clock [time.clock.steady]

\n

[...]

\n

stable_clock 类的对象表示这样的时钟:time_point 的值永远不会随着物理时间的推进而减小,并且 time_point 的值相对于实际时间以稳定的速率前进。也就是说,\n时钟可能无法调整。

\n
\n

就是这样。没有表示steady_clock与挂钟时间和任何特定的基于挂钟的起点有任何关系。因此,MS-Windows 自系统启动以来计算时间的实现也在该定义的范围内。

\n

现在,时钟确实会在下次启动时有效地自行重置,并且可以提出一个问题,这是否严格遵守“永不减少”的要求,但这将是一个不同的问题。到目前为止,为什么steady_clock不计算自 Unix 纪元以来的秒数,就像 一样system_clock,是因为 C++ 标准不要求这样做。

\n

  • 但前提是这种情况:Unix 上的 `steady_clock` 只是 `system_clock` 加上一个固定偏移量。这是非常非常不可能的。我没有看到任何证据。如果有的话,Unix 时间也可能以 1/1/1970 UTC 作为纪元,但也在秒内滴答,那么这仍然满足“steady_clock”要求。请注意,C++20 单独显式定义了“utc_clock”。 (2认同)