将 Qt 信号/槽与非 Qt 线程一起使用

Posted

技术标签:

【中文标题】将 Qt 信号/槽与非 Qt 线程一起使用【英文标题】:Using Qt signals/slots with non-Qt threads 【发布时间】:2015-01-14 16:04:09 【问题描述】:

我已尽职尽责,但找不到此问题的答案:

Qt 信号/槽机制如何与非 Qt 线程交互?

特别是,从非 Qt(例如TBB)线程发出信号,被我的主事件循环中的插槽捕获是否安全?假设我将它与排队连接显式连接? (我的感觉是指定连接排队是强制性的;这是正确的吗?)

(作为一个附带问题,我一直假设 Qt 同步类,例如 QMutex,可以跨非 Qt 线程工作。这是正确的吗?)

(澄清一下,我担心的是,如果队列连接机制没有检测到信号是从不同的 Qt 线程发出。)

(最后的补充:我可以相信,因为 Qt 机制是根据特定于平台的原语实现的,所以在实践中我尝试做的所有事情都会优雅地工作,但我也想知道是否Qt 提供任何保证这些东西会起作用。)

【问题讨论】:

【参考方案1】:

documentation 声明:

注意: Qt 的线程类是用原生线程 API 实现的;例如,Win32 和 pthreads。因此,它们可以与相同原生 API 的线程一起使用。

所以是的,Qt 的互斥锁可以与其他线程一起使用(只要它们也使用相同的本机 API)。

Qt 线程与其他线程的区别在于,其他线程永远不会运行 Qt 的事件循环,因此无法接收和处理任何信号。但是,如果您要在这样的线程中运行事件循环 (exec),那么一切都应该可以正常工作。

信号相关的函数,主要是processEventspostEvent,据说是线程安全的:

注意:这个函数是线程安全的。

如果对象正确设置了线程亲和性(使用moveToThread 方法),则无需显式设置连接类型,默认AutoConnection 工作方式如下:

(默认)如果信号在接收对象具有亲和性的线程中发出,则行为与直接连接相同。否则,行为与排队连接相同。

This answer 建议非 Qt 线程也应该可以通过 Qt 的方法正确识别 - 即使对于非 Qt 线程,currentThread 也应该返回一个 QThread 实例,因为它只是本机线程的包装器。

【讨论】:

以上是关于将 Qt 信号/槽与非 Qt 线程一起使用的主要内容,如果未能解决你的问题,请参考以下文章

Qt事件机制概览

Qt线程间的信号与槽 以及 QThread

QT中的信号与事件,多线程

Qt 线程基础(QThreadQtConcurrent信号槽等)

qt 通过将对象移动到跨线程发出信号

通过 Qt 信号/槽跨线程传递对象