[英]Is Qt's event loop thread safe or atomic? How is it synchronised when dealing with `QueuedConnection`?
假设2个QThread
运行以下关系:
connect(&Object1OfThread1, &Object1::Signal,
&Object2OfThread2, &Object2::Slot, Qt::QueuedConnection);
因此,当来自一个线程的对象发出信号时,将调用另一个线程的插槽。 如在Qt信号(QueuedConnection和DirectConnection)中所讨论的,由于Qt::QueuedConnection
, Signal()
被发布/追加到Thread2的事件循环中。 轮到时,将调用Slot()
。
问题 :事件循环本身是线程安全的吗?
即 如果Thread1和Thread3都同时向Thread2的事件循环发送信号该怎么办?
该注释中提到的文章说,事件队列受互斥锁保护。
Qt信号和插槽如何工作-第3部分-排队和线程间连接
QueuedConnection
会将事件发布到事件循环中,以最终得到处理。发布事件时(在
QCoreApplication::postEvent
),该事件将被推送到每个线程队列(QThreadData::postEventList
)中。 事件队列受互斥锁保护,因此当线程将事件推送到另一个线程的事件队列时,没有竞争条件 。一旦将事件添加到队列中,并且如果接收者住在另一个线程中,我们将通过调用
QAbstractEventDispatcher::wakeUp
通知该线程的事件调度QAbstractEventDispatcher::wakeUp
。 如果调度程序在等待更多事件时处于睡眠状态,这将唤醒调度程序。 如果接收者在同一个线程中,则事件将在以后迭代,因为事件循环会迭代。
Qt事件循环是线程安全的,但不是原子的。
线程安全
只要Object2OfThread2
状态始终由与Thread2
关联的线程修改,就不会有任何竞争条件。 任何时候最多只能执行一个插槽。
原子性
插槽的执行顺序受以下条件支配:
因此,我不建议为给定的插槽假定特定的执行顺序。
如果Thread1和Thread3都同时向Thread2的事件循环发送信号该怎么办
Object2OfThread2
所以它们首先获胜 。 Object2OfThread2, &Object2::Slot
之前进行的,则在将它们发布到Object2OfThread2
事件循环之前将对其进行处理。 如果信号同时发出 ,则Thread3信号将首先排队,因此要首先执行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.