我有一个我认为很简单的模式——我想在未来 5 秒内设定一个时间点,运行一个可能需要一段时间的任务,然后一直睡到那个时间点(如果那个时间点有可能根本不 sleep )已经达到。)但是,每当尝试将 std::this_thread::sleep_until
与过去的时间点一起使用时,我的应用程序就会永远挂起。这是一个 MCVE:
#include <chrono>
#include <thread>
int main(){
std::this_thread::sleep_until(std::chrono::steady_clock::now() - std::chrono::seconds(1));
}
使用 g++ (GCC) 4.8.5,这永远不会返回。我也试过 system_clock 得到了同样的结果。使用 strace 检查发生了什么,我得到的最后一件事是:
nanosleep({4294967295, 0},
所以我猜它最终会回来,但我不想等那么久。
这是 g++ 错误吗?我无法想象这种行为是故意的。我找到了问题 Is behaviour well-defined when sleep_until()
specifies a time point in the past?但对于该标准是否实际指定了应该发生的事情,似乎并没有真正得出任何结论。从那以后,我对我的问题实现了另一种解决方案;我只是想知道我看到的是 UB 还是错误。
最佳答案
看起来像一个错误:
30.2.4 Timing specifications [thread.req.timing]
4 The functions whose names end in
_until
take an argument that specifies a time point. These functions produce absolute timeouts. Implementations should use the clock specified in the time point to measure time for these functions. Given a clock time point argument Ct, the clock time point of the return from timeout should be Ct+Di+Dm when the clock is not adjusted during the timeout. (...)
其中 Di 定义为“实现质量”延迟,Dm 定义为“管理质量”延迟。
As Howard Hinnant brilliantly emphasizes , 一个实现应该努力最小化 Di 和 Dm:
30.2.4 Timing specifications [thread.req.timing]
2 Implementations necessarily have some delay in returning from a timeout. Any overhead in interrupt response, function return, and scheduling induces a “quality of implementation” delay, expressed as duration Di. Ideally, this delay would be zero. Further, any contention for processor and memory resources induces a “quality of management” delay, expressed as duration Dm. The delay durations may vary from timeout to timeout, but in all cases shorter is better.
请注意,无论 Ct 的值是多少,这都必须成立,而且无限延迟绝对不是最小的。
作为一个小更新,this is now fixed , 从版本 4.9.3 开始。 Here is the information on the bug tracker.
关于c++ - sleep_until 过去的某个时间点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51755266/