我有一个简单的模式-我想在未来5秒钟创建一个时间点,运行可能需要一段时间的任务,然后休眠直到该时间点(如果有时间,可能根本不休眠但是,每当尝试在过去的某个时间点使用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还是bug。
答案 0 :(得分:3)
看起来像个错误:
30.2.4时序规范[thread.req.timing]
4 名称以
_until
结尾的函数采用指定时间点的参数。 这些函数产生绝对超时。 实现应使用时间点中指定的时钟来测量这些功能的时间。 给定时钟时间点参数C t ,超时返回的时钟时间点应为C t + D i + D m ,如果在超时期间未调整时钟。 (...)
其中D i 被定义为“实施质量”延迟,而D m 被定义为“管理质量”延迟。
As Howard Hinnant brilliantly emphasizes,实现应努力使D i 和D m 最小:
30.2.4时序规范[thread.req.timing]
2 实现从超时返回中必然会有些延迟。 中断响应,函数返回和调度中的任何开销都会引起“执行质量”延迟,表示为持续时间D i 。 理想情况下,此延迟为零。 此外,对处理器和内存资源的任何争用都会引起“管理质量”延迟,表示为持续时间D m 。 延迟时间可能因超时而异,但在所有情况下,延迟时间都越长越好。
请注意,无论C t 的值是什么,这都必须成立,并且无限延迟绝对不是最小。
作为小更新this is now fixed,从4.9.3版开始。 Here is the information on the bug tracker.