Qt中的最佳生产者/消费者线程模式



我已经使用Qt线程实现了生产者/消费者模式。多个生产者线程生成由消费者组合的数据。使用信号/插槽和排队连接实现通信。只要使用者能够比生产者线程生成数据更快地消耗数据,这种方法就可以很好地工作。

很难使我的代码缩放。特别是增加生产者的数量很容易,但很难产生多个消费者线程。

现在,当在有很多核心的CPU/系统上运行软件时,问题就开始了。在这种情况下,我使用更多的线程来生成数据。消费者有时可能无法及时处理生成的数据(这取决于数据生成的复杂性(。然后,Qt事件队列中迅速充满了事件,内存消耗也急剧增加。

我可以通过使用阻塞排队连接来解决这个问题。然而,这不允许CPU满负荷,因为生产者往往在每次数据发射后不必要地等待消费者。

在非Qt软件中,我会使用一个固定大小的队列/邮箱/环形缓冲区,使生产者睡眠,直到消费者释放该容器中的空间。这种机制限制了内存消耗,并允许尽可能好的CPU负载。

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

在这种情况下,我认为您应该放弃使用Qt,因为虽然事件处理速度很快,但它显然不是为针对许多核心的HPC工作负载而设计的(因为集中的顺序事件队列(。因此,我认为您应该使用一个快速的原子多生产者/多消费者(MPMC(队列。虽然您可能会在此基础上编写一个Qt事件层,但我不确定这在性能方面是个好主意。另一种解决方案是使用可变大小的块来减少事件量(在生产者和消费者之间使用feedback loop(。请注意,关于您的工作负载,最好考虑使用基于任务的运行时(已知可扩展性很好(。

如果你正在搜索一个快速的MPMC队列,Boost提供的队列(Boost::lockfree::queue(不是很快,但这通常已经足够了。我所知道的最好的事情之一就是这个。它基于一篇研究论文,并在大型游戏中使用。在我的机器上,这一个在特定情况下稍微快一点,也更灵活,但在使用它时应该非常小心,因为并不总是确保一致性(即阅读文档(。请注意,线程库在队列的选择中应该无关紧要。

最新更新