繁体   English   中英

Qt的事件循环线程是安全的还是原子的? 处理“ QueuedConnection”时如何同步?

[英]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::QueuedConnectionSignal()被发布/追加到Thread2的事件循环中。 轮到时,将调用Slot()

问题 :事件循环本身是线程安全的吗?
如果Thread1和Thread3都同时向Thread2的事件循环发送信号该怎么办?

注释中提到的文章说,事件队列受互斥锁保护。

Qt信号和插槽如何工作-第3部分-排队和线程间连接

QueuedConnection会将事件发布到事件循环中,以最终得到处理。

发布事件时(在QCoreApplication::postEvent ),该事件将被推送到每个线程队列( QThreadData::postEventList )中。 事件队列受互斥锁保护,因此当线程将事件推送到另一个线程的事件队列时,没有竞争条件

一旦将事件添加到队列中,并且如果接收者住在另一个线程中,我们将通过调用QAbstractEventDispatcher::wakeUp通知该线程的事件调度QAbstractEventDispatcher::wakeUp 如果调度程序在等待更多事件时处于睡眠状态,这将唤醒调度程序。 如果接收者在同一个线程中,则事件将在以后迭代,因为事件循环会迭代。

Qt事件循环是线程安全的,但不是原子的。

线程安全

只要Object2OfThread2状态始终由与Thread2关联的线程修改,就不会有任何竞争条件。 任何时候最多只能执行一个插槽。

原子性

插槽的执行顺序受以下条件支配:

  • 通常的线程抢占
  • 到此插槽的连接顺序。
  • 其他插槽连接到信号。

因此,我不建议为给定的插槽假定特定的执行顺序。

如果Thread1和Thread3都同时向Thread2的事件循环发送信号该怎么办

  • 首先,它是不同的信号:两个线程不能发出相同对象的相同信号,因为该对象仅驻留在一个QObject中
  • 假定这些信号即使同时“发布”,也仅连接到Object2OfThread2所以它们首先获胜
  • 例如,如果Thread1信号连接到其他信号\\插槽,并且这些连接是在Object2OfThread2, &Object2::Slot之前进行的,则在将它们发布到Object2OfThread2事件循环之前将对其进行处理。 如果信号同时发出 ,则Thread3信号将首先排队,因此要首先执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM