我目前正在处理一些C ++代码,这些代码从视频文件中读取,将视频/音频流解析为其组成单元(例如FLV tag
),然后将其发送回去以进行“重播”它。
由于我的输入来自文件,但是我希望在重播此数据时模拟适当的帧速率,因此我正在考虑我可能会休眠在文件上执行read
的线程的方式,以尝试以给定的速率从典型的30或60 FPS中提取帧。
一种解决方案是使用明显的std::this_thread::sleep_for
调用并根据我的FPS传入毫秒数。我正在考虑的另一种解决方案是使用条件变量,并使用具有相同想法的std::condition_variable::wait_for
。
我有点困惑,因为我知道第一个解决方案不能保证精确的准确性-只要我传入的参数就可以持续睡眠,但是理论上可能更长。而且我知道std::condition_variable::wait_for
调用将需要重新获得锁,这也需要一些时间。有没有比我正在考虑的更好的解决方案?否则,尝试以尽可能精确的粒度暂停执行的最佳方法是什么?
答案 0 :(得分:-1)
C ++ 11最准确的方式将执行暂停一定时间?
此:
auto start = now();
while(now() < start + wait_for);
now()
是占位符,可用于系统中最精确的时间测量方法。
这类似于sleep
,就像互斥锁是自旋锁一样。就像自旋锁一样,它将在暂停时消耗所有CPU周期,但这正是您要的:暂停执行的最准确方法。在精度和CPU使用效率之间需要权衡:您必须选择对程序更重要的一个。
为什么它比
std::this_thread::sleep_for
更准确?
因为sleep_for
产生了线程的执行。结果,它的粒度永远不会比操作系统的进程调度程序更好(假设还有其他进程在争夺时间)。
上面显示的实时循环不会自愿放弃其时间片,将获得用于测量的时钟所提供的最高粒度。
当然,调度程序授予的时间片最终会用完,这可能在我们应该恢复的时间附近发生。减少这种影响的唯一方法是增加线程的优先级。在C ++中,没有标准的方法可以影响线程的优先级。完全摆脱这种影响的唯一方法是在非多任务系统上运行。
在多CPU系统上,您可能想做的一件事是设置线程亲和力,以使OS线程不会迁移到其他会引起延迟的硬件线程上。同样,您可能希望设置其他线程的线程亲和力,以使其与时间测量线程保持隔离。没有设置线程关联性的标准工具。
让T为您希望睡觉的时间,让G为sleep_for
可能超调的最长时间。
如果T大于G,则将sleep_for
用于T-G时间单位,而仅将实时循环用于最后的G-O时间单位(其中O是时间)会更有效。 sleep_for
被发现超调。
弄清楚什么是目标系统G可能非常棘手。没有标准的工具。如果您高估了,您将浪费更多的周期。如果您低估了睡眠时间,可能会超出目标。
如果您想知道now()
的最佳选择,则标准库提供的最合适的工具是std::chrono::steady_clock
。但是,这不一定是系统上可用的最准确的工具。哪种工具最准确取决于您所针对的系统。