c++ - sleep_until 过去的一个时间点
问题描述
我有一个我认为很简单的模式 - 我想在未来 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++ 错误吗?我无法想象这种行为是故意的。我发现问题在指定过去的时间点时行为是否明确?sleep_until()
但似乎并没有就该标准是否实际规定应该发生的事情得出任何结论。我已经为我的问题实施了另一种解决方案;我只是好奇我看到的是 UB 还是 bug。
解决方案
看起来像一个错误:
30.2.4 时序规范[thread.req.timing]
4 名称以结尾的
_until
函数采用指定时间点的参数。这些函数产生绝对超时。实现应使用时间点中指定的时钟来测量这些功能的时间。 给定一个时钟时间点参数 C t ,在超时期间不调整时钟时,从超时返回的时钟时间点应该是 C t +D i +D m 。 (...)
其中,D i被定义为“实施质量”延迟,而 D m被定义为“管理质量”延迟。
正如 Howard Hinnant 出色地强调的那样,实现应该努力使 D i和 D m最小化:
30.2.4 时序规范[thread.req.timing]
2 实现在从超时返回时必然会有一些延迟。中断响应、函数返回和调度中的任何开销都会导致“实现质量”延迟,表示为持续时间 D i。 理想情况下,此延迟为零。此外,任何对处理器和内存资源的争用都会导致“管理质量”延迟,表示为持续时间 D m。 延迟持续时间可能因超时而异,但在所有情况下,越短越好。
请注意,无论 C t的值是多少,这都必须是正确的,并且无限延迟绝对不是最小的。
作为一个小更新,从 4.9.3 版开始,此问题现已修复。这是有关错误跟踪器的信息。
推荐阅读
- css - 更改链接颜色,除了下面的
- 某类的
- sql - 从 select 内的子查询中选择一列?
- selenium - 如何识别 id 动态变化且在 selenium 中没有其他属性的元素?
- c++ - 如何使用 fprintf 将连续 512 字节保存到文件中
- javascript - 如何在 Vue.js 中捕获隐藏在 div 上的虚拟键盘
- oracle-sqldeveloper - Oracle SQL Developer 是否需要专用的 git 存储库?
- android - xamarin.android - 使用尺寸文件支持不同的屏幕尺寸
- autodesk-forge - 不支持文件扩展名:null 错误代码:13。加载多个模型时
- laravel-5.7 - Laravel 5.7 控制器检查已单击哪个按钮
- jquery - 使用动态值检测 URL 变化