【问题标题】:C++ synced stages multi thread pipelineC++ 同步阶段多线程管道
【发布时间】:2014-07-17 06:45:30
【问题描述】:

抱歉,如果有人问过这个问题,我在问之前已经尽力搜索了一个 dup...

我正在实现一个应该实时运行的视频处理应用程序。它所做的处理可以很容易地分为 4 个阶段,每个阶段都对前一阶段生成的中间值进行操作。处理变得比在 1/30 秒内可以处理的要重,但是如果我可以将此应用程序拆分为 4 个线程并将其转换为管道,则每个阶段所需的时间都会少于此,整个事情将实时运行(使用4 帧延迟,这是完全可以接受的)。

我对多线程编程相当陌生,我遇到的问题是,我找不到在每一帧开始时启动/停止每个线程的机制,所以他们都一起前进,交付一个完成在最后构建每个“周期”。我发现的所有框架/库似乎都担心使用队列和工作线程进行负载平衡,但这不是我在这里需要的。四个线程都可以,假设我可以让它们保持同步。

谁能指出我使用 C++ 的起点吗?

谢谢。

【问题讨论】:

  • 您是否在使用线程库(即 boost)?还是普通的 POSIX?
  • 可能是std::condition_variable 可以帮助您解决问题。可以基于它构建类似信号量的同步机制(另见this question)。
  • @wbennett,我还没有使用任何东西,完全接受建议。该应用程序现在都在一个线程中运行(GUI 除外)。
  • @πάνταῥεῖ,查看了链接......似乎我可以使用它来工作,但它看起来像一个可怕的黑客......没有像时钟这样的机制吗?处理器的管道如何工作?在每个循环中,所有线程都从同一个地方获取输入,并将它们的输出写入同一个地方? (不用担心比赛条件或数据覆盖,这是完全不同的阶段之间的数据)。
  • 您可能需要重新考虑这个问题。如果您有一个依赖于下一个阶段的阶段,那么您的速度只会与最慢的阶段一样快(参见阿姆达尔定律)。也许可以考虑水平划分工作而不是垂直划分以加快每个阶段的速度。特别是如果您有软实时要求。

标签: c++ multithreading video pipeline


【解决方案1】:

假设 4 帧延迟是可以接受的,您可以使用列表节点池,每个节点都有一个指向帧缓冲区的指针和一个指向中间值的指针(可以使用 NULL 指针来指示流的结束)。每个线程都有自己的列表作为多线程消息传递系统的一部分。第一个线程将从空闲池中获取一个帧节点,进行处理并将节点发送到下一个线程列表,依此类推,最后一个线程将节点返回到空闲池。

这里是一个示例文件复制程序的链接,该程序生成一个线程来执行写入。它在消息传递函数中使用 Windows 线程、互斥体和信号量,但消息传递函数很简单,可以在内部进行更改以使用通用等效项,而无需更改其接口。 main() 函数可以更改为使用通用线程和设置互斥锁和信号量或等效的东西。

mtcopy.zip

【讨论】:

  • 感谢您的建议和源代码,非常有帮助。但是,我试图避免线程之间的整个池/队列消息传递,因为我认为它不符合我算法的性质。线程永远不会“超越”彼此,它们都在来自视频源的帧之间的间隔内完成它们的工作。我只需要一种机制来同时告诉所有线程何时开始在新帧上工作(每个线程都是处理管道的一部分)。如果这是有道理的......
  • 权衡是一个有点尴尬的启动顺序,因为它是一个分阶段的过程(基于您的帖子,每个线程都使用从另一个线程产生的中间值)。在第一个线程完成第一帧之前,第二个线程没有任何事情要做。在第三个线程完成第一帧之前,第四个线程没有任何事情要做。使用消息系统简化了启动,如果你看示例代码,实际的消息功能很小。
  • 消息传递的替代方法是使用事件或条件变量来触发每个线程。
猜你喜欢
  • 1970-01-01
  • 2011-12-28
  • 1970-01-01
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 2022-01-04
  • 2022-10-05
相关资源
最近更新 更多