BlockingQueue 的等价物是每个QObject
. 它没有在 QObject 的 Qt 文档中明确说明(应该是这样!),但是对于每个 QObject 都有一个有效的事件队列。您可以使用静态QCoreApplication::postEvent
方法从任何线程向任何 QObject 发布事件——只要您有一个指向 QObject 的指针,您就可以向它发布事件。
该类型的信号槽连接Qt::QueuedConnection
使用相同的事件队列来发布内部QMetaCallEvent
事件。这些事件被拾取QObject::event()
并导致对相关插槽的调用。当控制返回到线程的事件循环时,后者查看事件队列并将事件传递给QObject::event()
方法。
那些内置的事件队列非常有用,因为它们本质上允许您序列化对 QObject 的访问,因此您不必添加额外的同步原语,并且您可以避免陷入死锁。使用 ad-hoc 同步会带来麻烦,不幸的是,即使是 Java 在设计上也出错了。请参阅 Herb Sutter 关于此主题的出色公开:死锁的许多方面和避免在关键部分中调用未知代码。他有很多关于这个和相关主题的其他出版物,这是一个真正的知识宝库。他还解释了如何设计从运行到完成的、简短的异步应用程序以获得良好的性能。
如果您的设计基于 QObjects 以及它们之间使用信号槽和事件发布的连接,那么如果您的分析/基准测试表明需要这样做,您就可以将这些 QObjects 中的任何一个移动到专用的 QThread。但是,任何从 QWidget 派生的东西都不能离开 GUI 线程。