4

一个线程做一个emit signal1();

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

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

是否有任何保证 signal1 的 slot 会在 signal2 的 slot 之前被调用?

4

3 回答 3

6

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

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

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

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

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

当一个信号发出时,连接到它的槽通常会立即执行,就像一个普通的函数调用一样。

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

因此,可以将调用 emit() 视为调用任何其他函数。

于 2012-11-05T11:16:55.077 回答
1

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

因此,emit signal1();编译为signal1();,并且您的问题的答案是肯定的,但是您当然不能保证 signal1() 执行在 signal2() 调用之前结束。

于 2012-11-05T11:21:39.677 回答