发出和插槽顺序执行

时间:2012-11-05 10:56:12

标签: qt signals

一个帖子执行emit signal1();

第二个线程在第一个线程发出信号之后执行emit signal2();(在两个线程上发出调用之前锁定了相同的互斥锁并且我记录了它,我可以在我的日志中看到第一个线程获取锁定在第二个线程之前)

第一个线程和第二个线程或不是GUI线程。

是否有任何guarentees信号1的插槽将在signal2的插槽之前调用?

3 个答案:

答案 0 :(得分:6)

由于发射器和接收器对象在不同的​​线程中运行,因此不会同步执行插槽:Qt默认使用排队连接而不是直接连接。但是,在连接信号和插槽时,您可以使用阻塞排队连接强制执行同步执行(另请参阅http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-enum了解不同连接类型的说明)。

但阻塞队列连接有一个成本:发射器线程被阻塞,直到所有连接的槽都被执行,这不一定是个好主意。但是,如果要使用非阻塞连接,则执行顺序取决于执行插槽时的对象。

需要考虑的重要事项是每个QThread都有自己的事件队列。这意味着只保证给定线程的槽的执行顺序。这意味着您必须考虑以下情况:

  • signal1的slot和signal2的槽在QObject中定义,位于同一个线程中:在这种情况下,您可以确定槽是按预期顺序执行的,因为它们是由同一个事件队列触发的。
  • 两个插槽都在不同的线程中运行:在这里,您无法控制执行顺序,因为信号被发布到2个独立的事件队列。如果是这种情况,则必须使用互斥锁或等待条件(或使用阻塞连接)。

答案 1 :(得分:1)

我不确定我是否理解正确,但这可能会对您有所帮助:

  

当发出信号时,通常会立即执行与其连接的插槽,就像正常的函数调用一样。

来自http://doc.qt.io/qt-5/signalsandslots.html

所以考虑将emit()称为调用任何其他函数。

答案 2 :(得分:1)

emit只是语法糖,请查看元对象编译器(moc)生成的.cpp。

所以,emit signal1();被编译为signal1();,你的问题的答案是肯定的,但当然你没有在signal2()调用之前signal1()执行结束的guarentees。