首先,信号槽连接是在 QObjects 中的信号和槽之间完成的,而不是在线程之间。好吧,QThread 是一个 QObject,但你真的不应该从 QThread 派生。不要从 QThread 派生,你会没事的。
你要做的是:
启动一个或多个 QThreads (不仅仅是构造)。那些 QThreads 只是 Qt 的基类,不要从它们派生。一个启动的原始 QThread 被阻塞,等待一个事件被发布到它的事件队列中。QThread::run()
调用的默认实现QEventLoop::exec()
(或等效的)。因此,这些线程在启动后不会消耗任何 CPU 周期。
实例化一堆 QObject。根据需要进行所有信号/插槽连接。
通过调用这些对象将它们移动到一个或多个 QThread moveToThread(QThread*)
。
如您所见,设置信号槽连接以通常的方式完成,不需要任何特别注意。Qt 为您做所有事情,包括在您在线程之间移动 QObject 时Qt::DirectConnection
更改连接类型。Qt::QueuedConnection
请注意,您不能直接在这些 QObjects 上调用任何方法,因为您可能会从不同的线程这样做,因此由于访问未序列化,会发生各种不好的事情。您必须按照从最快到最慢的顺序执行以下任何一项操作,并且仅此一项。请注意,虽然 #3 总是比 #4 快,但您需要在 #2 和 #3 之间进行基准测试,因为它会有所不同。
将自定义事件发布到 QObject,并在派生的 QObject 的customEvent(QEvent*)
方法中处理它。
使用信号槽连接,并发出连接到 QObjects 槽的信号。
用于QMetaMethod::invoke
先前查找的方法。比 #4 更快,因为方法查找只提前完成一次。
使用QMetaObject::invokeMethod
.
将 QEvents 发布到 QObjects 比使用信号槽调用更快,因为没有调用复制构造函数,并且除了在构造 QEvent 时直接由您完成之外没有编组。
仅当分析/基准测试显示事件发布太慢时,您才想使用QSharedMemory
. 拥有过多数量的 QThreads 会适得其反,您应该拥有的 CPU 核心数量可能不超过系统上的数量。天真地使用诸如互斥锁或信号量之类的同步原语需要您提交太多线程。您绝对不希望每个连接有一个线程!通过使用您已经使用的事件队列,Qt 已经为每个 QObject 提供了一个事件队列互斥锁。