将 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
),那么一切都应该可以正常工作。
信号相关的函数,主要是processEvents
和postEvent
,据说是线程安全的:
注意:这个函数是线程安全的。
如果对象正确设置了线程亲和性(使用moveToThread
方法),则无需显式设置连接类型,默认AutoConnection
工作方式如下:
(默认)如果信号在接收对象具有亲和性的线程中发出,则行为与直接连接相同。否则,行为与排队连接相同。
This answer 建议非 Qt 线程也应该可以通过 Qt 的方法正确识别 - 即使对于非 Qt 线程,currentThread
也应该返回一个 QThread
实例,因为它只是本机线程的包装器。
【讨论】:
以上是关于将 Qt 信号/槽与非 Qt 线程一起使用的主要内容,如果未能解决你的问题,请参考以下文章