Qt 中的最佳 producer/consumer 线程模式

Optimal producer/consumer thread pattern in Qt

我已经使用 Qt 线程实现了 producer/consumer 模式。多个生产者线程生成由消费者组合的数据。通信是使用 signals/slots 和排队连接实现的。只要消费者能够比生产者线程生成数据更快地使用数据,这就可以正常工作。

很难扩展我的代码。特别是增加生产者的数量很容易,但是产生一个以上的消费者线程就很难了。

现在,当 运行 具有很多内核的 CPU/system 上的软件时,问题就开始了。在那种情况下,我使用更多线程来生成数据。有时会发生(取决于数据生成的复杂性)消费者无法及时处理生成的数据。然后Qt事件队列很快被事件填满,内存消耗急剧增加。

我可以通过阻塞排队连接来解决这个问题。但是,这不允许完全 CPU 负载,因为生产者往往会在每次数据发出后不必要地等待消费者。

在非 Qt 软件中,我会使用固定大小的 queue/mailbox/ring-buffer,使生产者休眠,直到消费者释放该容器中的 space。这种机制限制了内存消耗并允许最好的 CPU 负载。

但是我找不到使用 Qt 的等效解决方案 类。事件队列是全局的,没有大小 属性。有没有一种 Qt 方法可以最佳地解决这个问题?如果没有,是否有 STL 类 我可以用我的方式耦合 (Q)Threads?

我认为在这种情况下您应该放弃使用 Qt,因为虽然事件处理速度非常快,但它显然不是为针对多核的 HPC 工作负载设计的(因为集中式顺序事件队列)。所以我认为你应该使用快速 atomic muti-producer/multi-consumer (MPMC) queue。虽然您可能会在此之上编写一个 Qt 事件层,但我不确定这在性能方面是否是个好主意。另一种解决方案是使用 可变大小的块 来减少事件的数量(在生产者和消费者之间使用 反馈循环 )。请注意,关于您的工作负载,最好考虑使用 基于任务的运行时(已知可以很好地扩展)。

如果您正在寻找一个快速的 MPMC 队列,Boost 提供了一个队列(boost::lockfree::queue) which is not very fast, but this is often enough. One of the best I am aware of is this one. It is based on a research paper and used in big games. This one 在我的机器上在特定情况下速度稍快并且更灵活,但您在使用它时应该非常小心因为并不总是保证一致性(即阅读文档)。请注意,线程库在队列的选择中应该无关紧要。