Qt的signal和slot是同步的,还是异步的?

我们知道Qt以他的signal和slot机制独步天下。但大家在用的时候有没有注意过,signal和slot是异步的,还是同步的呢?为此我问过不少Qt的使用者,有人说是同步的,有人说是异步的,也有人说着要看Qt的当时心情了¥%&*

其实是异步还是同步,是用户决定的。如果大家仔细看过connect函数的介绍就知道,connect最后的有一个参数 Qt::ConnectionType type 他将决定是异步还是同步(具体的类型可以参见帮助)。只不过平常我们使用的时候,他默认成了Qt::AutoConnection。有的兄台看到这里的时候,就会问,啥是Auto模式。其实Auto模式,就是看Qt的心情来决定是异步还是同步。而决定这个心情的就是,sender和receiver的他们分别所处的线程。如果是同一线程则就是同步调用,如果不在同一线程就是异步调用。

但真相果真如此吗?正像青春永驻的柯南君所指出的,真相永远都隐藏在表面之下。

请各位看官思考以下案例:

class A : public QObject

{

friend class B;

Q_OBJECT


public:

A ()

{

connect(this,SIGNAL(signalTest()),this,SLOT(slotTest()), Qt::AutoConnection);

}


  ............

signals:

void signalTest();

public slots:

void slotTest();


}


如果这时候我在另外一个线程触发signalTest(), 这时候signalTest和slotTest是同步还是异步呢? 根据帮助的说明,在Auto模式下,如果sender和receiver在同一线程里,

应该是同步调用。

但真相却是,他们是异步调用的。

参见Qt代码,

  // determine if this connection should be sent immediately or
            // put into the event queue
            if ((c->connectionType == Qt::AutoConnection
                 && (currentThreadData != sender->d_func()->threadData
                     || receiver->d_func()->threadData != sender->d_func()->threadData))
                || (c->connectionType == Qt::QueuedConnection)) {
                queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
                continue;
            } else if (c->connectionType == Qt::BlockingQueuedConnection) {
                blocking_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
                continue;
            }

从代码我们可以看出,在Auto模式下,如果当前线程不和sender是同一个线程,即使receiver和sender在同一线程,也将是异步调用。

太凶残了



猜你喜欢

转载自blog.csdn.net/SuperFPE/article/details/6625421