C++11 暂停执行一定时间的最准确方法?
C++11 Most accurate way to pause execution for a certain amount of time?
我目前正在研究一些C++代码,这些代码从视频文件中读取,将视频/音频流解析为其组成单元(例如FLV tag
)并将其发送回以"重新流式传输"它。
因为我的输入来自文件,但我想在重播此数据时模拟适当的帧速率,所以我正在考虑如何让对文件执行read
的线程休眠,以便尝试以给定的速率提取帧,人们可能期望从典型的 30 或 60 FPS 中获取帧。
一种解决方案是使用明显的std::this_thread::sleep_for
调用并根据我的 FPS 传入毫秒数。我正在考虑的另一种解决方案是使用条件变量,并以相同的想法使用std::condition_variable::wait_for
。
我有点卡住了,因为我知道第一个解决方案不能保证精确的精度 - 睡眠会持续到我传递的论点,但理论上可能会更长。而且我知道std::condition_variable::wait_for
调用将需要重新获取锁,这也需要一些时间。有没有比我正在考虑的更好的解决方案?否则,尝试暂停执行以尽可能精确粒度的最佳方法是什么?
C++11 暂停执行一定时间的最准确方法?
这:
auto start = now();
while(now() < start + wait_for);
now()
是可用于系统的最准确时间测量方法的占位符。
这是sleep
的类似物,就像自旋锁是互斥锁一样。就像旋转锁一样,它会在暂停时消耗所有 CPU 周期,但这正是您要求的:暂停执行的最准确方法。在准确性和 CPU 使用率效率之间需要权衡:您必须选择哪个对你的程序更重要。
为什么它比
std::this_thread::sleep_for
更准确?
因为sleep_for
会产生线程的执行。因此,它永远不会有比操作系统的进程调度程序更好的粒度(假设有其他进程在竞争时间)。
上面显示的实时循环不会自愿放弃其时间片,它将实现用于测量的时钟提供的最高粒度。
当然,调度程序授予的时间片最终会用完,这可能会发生在我们应该恢复的时间附近。减少这种影响的唯一方法是增加线程的优先级。没有标准方法来影响线程在C++中的优先级。完全摆脱这种影响的唯一方法是在非多任务系统上运行。
在多 CPU 系统上,您可能想要执行的一个技巧是设置线程关联,以便操作系统线程不会迁移到其他会导致延迟的硬件线程。同样,您可能希望设置其他线程的线程相关性,以远离时间测量线程。没有用于设置线程相关性的标准工具。
让 T 是您希望睡觉的时间,让 G 是sleep_for
可能超调的最长时间。
如果 T 大于 G,则对 T - G 时间单位使用sleep_for
会更有效,并且仅将实时循环用于最终的 G - O 时间单位(其中 O 是观察到sleep_for
超调的时间)。
然而,弄清楚目标系统的G是什么可能非常棘手。没有标准工具。如果你高估了,你会浪费比必要的更多的周期。如果你低估了,你的睡眠可能会超过目标。
如果您想知道什么是now()
的好选择,标准库提供的最合适的工具是std::chrono::steady_clock
。但是,这不一定是系统上可用的最准确的工具。哪种工具最准确取决于您的目标系统。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- C++11 暂停执行一定时间的最准确方法?
- 暂停低级钩子(Winapi)的最佳方法
- COM 方法仅在使用暂停间隔调用时返回正确的值
- 频繁暂停和重启线程的最佳方法是什么?
- 使用 std::atomic 与 std::condition_variable 在 C++ 中暂停和恢复 std::thread 的方法
- Linux:有没有一种方法可以在不停止/暂停进程的情况下使用ptrace(SIGSTOP)
- 什么是长时间暂停exe的最佳方法