具有异步事件的顺序算法

时间:2012-07-01 11:00:26

标签: qt signals

我目前(重新)设计了一个由几个部分组成的系统:

  • 第一部分是(异步)从源获取帧并在每次帧就绪时触发事件的实体 - 通过Qt信号。
  • 第二部分是一个GUI,它实时显示帧并通过插槽连接到上述信号
  • 最后一部分是帧处理器,其行为最好用顺序算法描述(而for,for等),有可能响应来自GUI的几种信号。

主要问题是是否有组织此类代码的最佳做法

我提出并且不太喜欢的解决方案是:运行4个线程。

  • 通过Qt信号与3个其他线程进行通信的GUI线程
  • 帧源线程,在每个帧可用性上发出信号。
  • 帧组织器线程,它在信号上存储帧并使用QWaitCondition通知帧处理器线程。
  • 帧处理器线程,它从帧组织器调用getNextFrame()。

但是我觉得这可能是一个很好的解决方案,因为混合了不同的范例(等待条件和信号)。此外,等待条件可能导致事件处理队列的饥饿。

1 个答案:

答案 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,例如,这样数据库就不会阻塞使用它的线程。