C++11 暂停执行一定时间的最准确方法?

C++11 Most accurate way to pause execution for a certain amount of time?

本文关键字:方法 暂停 执行 定时间 C++11      更新时间:2023-10-16

我目前正在研究一些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。但是,这不一定是系统上可用的最准确的工具。哪种工具最准确取决于您的目标系统。