【问题标题】:Is relation between this_thread::sleep_for and chrono clocks specified by C++11 standard?this_thread::sleep_for 和 C++11 标准指定的计时时钟之间的关系?
【发布时间】:2020-10-28 14:24:30
【问题描述】:

考虑以下代码:

using namespace std;
using namespace std::chrono;
typedef std::intmax_t intmax_type;

steady_clock::time_point start = steady_clock::now();

this_thread::sleep_for(chrono::milliseconds(25000));

steady_clock::duration dur = steady_clock::now() - start;

intmax_type desired_dur = duration_cast<milliseconds>(dur).count();

if(desired_dur < intmax_type(25000))
    std::cout << "WTF happend there?" << std::endl;

根据标准,std::this_thread::sleep_for(sleep_duration) 可能会因为调度或资源争用延迟而阻塞比sleep_duration 更长的时间,但至少它会阻塞指定sleep_duration 的线程执行。

可能存在线程实际休眠指定持续时间但由于std::chrono::steady_clockstd::chrono::system_clock使用与sleep_for实现不同的操作系统时钟(不同粒度fe)时间段测量给我们的结果与实际休眠时间不同的情况是。

我的问题是:

C++11 标准是否禁止条件if(desired_dur &lt; intmax_type(25000)) 发生?如果有,请提供准确的报价。

【问题讨论】:

    标签: c++ c++11 language-lawyer


    【解决方案1】:

    C++11/14/17/20 禁止desired_dur &lt; intmax_type(25000)true

    Here is the spec for this_thread::sleep_for:

    效果:rel_time指定的相对超时(32.2.4)内阻塞调用线程。

    The reference to 32.2.4 is here. 这是一个非常冗长的部分,它将rel_time 定义为相对超时。可能最重要的段落是 p3:

    名称以_for 结尾的函数接受一个参数 指定持续时间。这些函数产生相对超时。 实现应该使用稳定的时钟来测量这些时间 函数。326 给定一个持续时间参数Dt, 超时的实时时长为Dt + Di + Dm.

    326) 标准时间单位对其有意义的所有实现都必须在其硬件实现中具有稳定的时钟。

    该部分将 Di 定义为“实施质量”延迟,并将 Dm 定义为“管理质量”延迟。这些定义暗示(通过使用“延迟”)它们是持续时间的非负量。

    “稳定时钟”一词从未真正定义过,但the standard does say this about steady_clock

    steady_clock 类的对象代表时钟,其值为 time_point 永远不会随着物理时间的推移而减少 time_point 的值以相对于实时的稳定速率前进。 也就是说,时钟可能无法调整。

    句子中“应该”一词的使用:

    实现应该使用稳定的时钟

    是回旋余地。 “应该”的意思:

    我们真的希望您这样做,但您不必这样做。如果你不这样做,你仍然可以称自己为顺从。

    这里使用“should”而不是“shall”,因为没有完美的时钟,尤其是在您的消费级计算机中。

    【讨论】:

    • 感谢您的详细回答,但我不明白为什么它被标准禁止。首先考虑使用非单调时钟的“sleep_for”(不应该,是吗?) - 每个操作系统时间偏移都可能导致结果不准确,对吗?那么 - 如果我们使用 'chrono::system_clock' 而不是 stable 来测量时间呢?最后但并非最不重要的一点——如果“sleep_for”实现使用单调时钟№1,但“chrono::steady_clock”使用单调时钟№2——它是否应该按标准同步?如果不是,那就是问题所在。
    • 编写标准规范非常困难。对于标准中相对复杂的任何内容,总有一种方法可以阅读允许实现做疯狂事情的​​标准。因此,人们还必须查看“合理解释”下措辞的意图。也没有标准的警察。实施最终只对客户负责。如果根据客户的判断,一个实施完全不符合标准(并且如果客户重视符合标准),那么它就会倒闭。
    • 最终的问题是:如果一个实现做了一些你认为不正确的事情,你能引用标准来支持你的错误报告吗?并且错误确实发生在这个区域。我知道一种将rel_time 向下舍入而不是向上舍入到下一个“可睡眠”持续时间精度的实现。我不确定这个错误是否已经修复。
    • 抱歉,您是在谈论实现中的错误以及实现标准库的一些“C++ 标准方式”/“常识”。当然,如果使用“chrono”时钟对完全相同的标准库进行时间测量将返回与“this_thread::sleep_for”的实际睡眠时间不同的结果(小于),那将是很奇怪的。但是,我的问题是 C++11 标准是否禁止或为什么不禁止实现这种奇怪的行为。就是这样。
    • 为了更全面地理解您对当前措辞的反对意见,我需要知道您将如何改进它。建议改进标准措辞的最佳方式是提交建议措辞的问题。每个人都可以这样做(就像一个开源项目)。以下是有关如何执行此操作的详细说明:cplusplus.github.io/LWG/lwg-active.html#submit_issue
    猜你喜欢
    • 2011-05-25
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 2016-10-03
    • 2016-05-18
    • 1970-01-01
    相关资源
    最近更新 更多