我目前(重新)设计了一个由几个部分组成的系统:
主要问题是是否有组织此类代码的最佳做法?
我提出并且不太喜欢的解决方案是:运行4个线程。
但是我觉得这可能是一个很好的解决方案,因为混合了不同的范例(等待条件和信号)。此外,等待条件可能导致事件处理队列的饥饿。
答案 0 :(得分:1)
无需使用QWaitCondition
。线程应该是裸的(非派生的)QThreads
。将您移动到这些线程的所有代码放在QObjects
中。帧组织器简单地将信号发送到帧处理器。通过将事件发布到线程的事件循环,跨线程边界传递信号。这些事件循环在内部使用同步原语(互斥)来分隔访问,因此不需要在那里重新发明轮子。 QThread的run()
的默认实现只是旋转一个事件循环,因此除了实例化线程并启动它之外,你不需要做任何事情。
您的代码应该运行,可能性能降低,所有QObject都在GUI线程中实例化。当您的基准测试显示哪些对象受CPU限制时,将它们移动到单独的线程。这条规则有一个令人遗憾但必要的例外:如果您的摄像头代码只能使用摄像头驱动程序提供的阻止API(等待某些东西而不是异步报告它的API),那么你别无选择,只能为此牺牲一个线程。 。除了这些专用的阻塞变通线程之外,您的应用程序应该使用与可用核心(QThread::idealThreadCount()
)一样多的线程。您将实例化该数量的线程,并随机或以循环方式在这些线程中分发QObject。再次 - 仅移动受CPU限制的QObject。使用非阻塞APis(网络!)的IO绑定对象不需要这种处理。 Sane设备驱动程序(如来自http://www.ftdichip.com/)公开异步事件通知,可以通过QWinEventNotifier
转换为信号。它是Qt 4.x中的一个私有API,但尽管如此仍然可以正常工作。
很多常见的API都存在阻塞,这真的很可悲。数据库驱动程序就是典型的例子我最终移植了mysql客户端驱动程序以使用QTcpSocket
,例如,这样数据库就不会阻塞使用它的线程。