http://blog.csdn.net/tingsking18/article/details/5157811
版权声明
本文为原创作品,请尊重作者的劳动成果。转载必须保持文章完整性,并以超链接形式注明原始作者“ tingsking18 ”和 主站点 地址,方便其他朋友提问和指正。
QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数
QT源码解析(六)Qt信号槽机制与事件机制的联系
在QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)文章中遗留了一个问题,就是当signal和slot的连接为Qt::QueuedConnection,这时候这个连接是怎么分发处理的。下面就结合一下Qt的源
代码来分析一下。
- 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, *c, argv);
- continue;
- } else if (c->connectionType == Qt::BlockingQueuedConnection) {
- blocking_activate(sender, signal, *c, argv);
- continue;
- }
这段代码的意思是:当前connectionType为Qt::AutoConnection并且,signal和slot不在一个线程或者是signal和不再当前线程中;或者是c->connectionType为 Qt::QueuedConnection这时候调用函数
queued_activate,如果c->connectionType 为Qt::BlockingQueuedConnection则调用函数blocking_activate
我们当queued_activate和blocking_activate一样就可以了。
queued_activate函数很简单,就是对参数转换一下,然后调用
QCoreApplication::postEvent(c.receiver, new QMetaCallEvent(c.method,sender,signal,nargs,types,args,semaphore));
注意: postEvent第二个参数是QMetaCallEvent。这样这个signal-slot的connection就发送到receiver的消息队列中去了。
接下来消息队列如何处理QMetaCallEvent,请参考 QT源码解析(四)剖析Qt的事件机制原理。
后记:通过这种方法Qt实现了跨线程的signal-slot传递,并且这种signal-slot机制的传递是利用消息队列,所以说是线程安全的。