QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)
来源:互联网 发布:双层玻璃杯 知乎 编辑:程序博客网 时间:2024/04/26 18:49
请尊重原创作品。转载请保持文章完整性,并以超链接形式注明原始作者“tingsking18”和主站点地址,方便其他朋友提问和指正。 版权声明
QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数
QT源码解析(二)深入剖析QT元对象系统和信号槽机制
QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)
QT源码解析(四)剖析Qt的事件机制原理
QT源码解析(五)QLibrary跨平台调用动态库的实现
QT源码解析(六)Qt信号槽机制与事件机制的联系
QT源码解析(七)Qt创建窗体的过程
QT源码解析(八)Qt是如何处理windows消息的
QT源码解析(九)解析QDateTime
看到了网友toto07的提问:
我看到过这样的论断: "signal和slot机制与GUI的事件循环完全没有关系,当所有链接到这个signal的slot执行完成之后,在emit代码行之后的代码才会被执行。" "当emit一个信号后,只有在所有与之相连的信号或槽返回后,emit才会返回。" 这2句话说的是同一个意思,但它们对吗? 1. 这2句话是不是针对单线程的,或者说是在同一个线程中的信号和槽? 2. 当线程A,B同时向另一个线程C的同一个槽发射信号时,如果线程C没有自己的事件循环,那些发过来的信号会排队吗,还是会丢失? 如果有事件循环情况又如何? 3. 接上面的问题2,假设GUI线程是D,线程C的对象存在于D,那C的槽函数是在C中还是在D中被执行的呢? 4. 线程A在向C发射信号后,会向开头那些话所说的,在C的槽返回之后再执行emit之后的信号么?
发现,在上一篇对信号槽极致的分析还不是那么透彻。下面专门来回答一下toto07网友的问题。
首先我们来看一段代码:
在pro文件中要指定: CONFIG += console QT -= gui 这样,我们就没有使用gui部分。 这是生成的Makefile部分: LIBS = d:/qt4.4.3/lib/QtCored4.lib 很明显,我们只用了QtCored4.lib部分,并咩有使用Gui部分。所以说QT的signal、slot机制于Gui没有关系。 下面是运行结果,从运行结果很明显能看得出来: C:/test1/debug>test1.exe We have two counters, 0 and 10 10 Counter1 slot executed 11 Counter1 slot executed Counter emit executed 很明显: 是slot首先执行,然后是emit后面的代码再继续执行,看起来貌似signal和slot是阻塞的。下面我们在看一下toto07朋友说的第二种情况: 添加线程类:
然后把main函数改成如下形式:
我们再来看一下运行结果:
C:/test1/debug>test1.exe
11 Counter1 slot executed
Counter emit executed
12 Counter1 slot executed
Counter emit executed
和上面的所有的操作在单线程中的结果有所不同,这时候是slot执行之后,直接返回,继续执行emit后面的代码。
貌似这时候结论已经出来了,单线程和多线程的执行结果不同。就如上面的测试结果一样。但是事实是这样么?
如果你仔细看了我的上一篇QT源码解析的文章:QT源码解析(二)深入剖析QT元对象系统和信号槽机制
在src/corelib/kernel/qobject.cpp文件的void QMetaObject::activate函数中。
文章:QT源码解析(二)深入剖析QT元对象系统和信号槽机制也对activate函数做了详细的解释,下面我再解释一下。
其中最关键的地方就是这里:
if ((c.type == Qt::AutoConnection
&& (currentQThreadId != sender->d_func()->thread
|| c.receiver->d_func()->thread != sender->d_func()->thread))
|| (c.type == Qt::QueuedConnection))
打开QAssistant,找到:
bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionType type = Qt::AutoConnection ) [static]
看到了,原来connect是5个参数,其中第五个参数
Qt::ConnectionType type = Qt::AutoConnection是有默认值的,我们再看一下
Qt::ConnectionType
Constant
Value
Description
Qt::DirectConnection
1
When emitted, the signal is immediately delivered to the slot.
Qt::QueuedConnection
2
When emitted, the signal is queued until the event loop is able to deliver it to the slot.
Qt::BlockingQueuedConnection
4
Same as QueuedConnection, except that the current thread blocks until the slot has been delivered. This connection type should only be used for receivers in a different thread. Note that misuse of this type can lead to dead locks in your application.
Qt::AutoConnection
0
If the signal is emitted from the thread in which the receiving object lives, the slot is invoked directly, as with Qt::DirectConnection; otherwise the signal is queued, as with Qt::QueuedConnection.
Qt支持三种类型的信号-槽连接:
1,直接连接,当signal发射时,slot立即调用。此slot在发射signal的那个线程中被执行(不一定是接收对象生存的那个线程)
2,队列连接,当控制权回到对象属于的那个线程的事件循环时,slot被调用。此slot在接收对象生存的那个线程中被执行
3,自动连接(缺省),假如信号发射与接收者在同一个线程中,其行为如直接连接,否则,其行为如队列连接。
连接类型可能通过以向connect()传递参数来指定。注意的是,当发送者与接收者生存在不同的线程中,而事件循环正运行于接收者的线程中,使用直接连接是不安全的。同样的道理,调用生存在不同的线程中的对象的函数也是不是安全的。QObject::connect()本身是线程安全的。
这样toto07的问题就有答案了。
- QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)
- QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)
- QT源码解析(二)深入剖析QT元对象系统和信号槽机制
- QT 源码之QT元对象系统和信号槽机制
- 【QT】信号和槽机制(三)
- Qt元对象系统解析(一)
- QT源码解析(六)Qt信号槽机制与事件机制的联系
- Qt信号-槽源码解析(二)
- Qt信号-槽源码解析(一)
- Qt--深入信号和槽机制
- 【QT】信号和槽机制(一)
- 【QT】信号和槽机制(二)
- QT源码解析(四)剖析Qt的事件机制原理
- QT源码解析(四)剖析Qt的事件机制原理
- Qt 信号槽机制解析三 补充解释源代码
- Qt元对象系统和模板机制的冲突
- 深入信号和槽---QT
- Qt 元对象机制
- 猜数字游戏(c语言程序)
- 求某一天是星期几
- 642-736 Cisco
- 工作VS爱情
- 《PHP和MySQL Web开发》笔记之使用PHP(一)
- QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)
- 创建透明表时的细节
- 分页机制代码详细注释
- jquery报错: "object expected"
- 发NEC中国研究院实习生面经
- 公司简介
- Trac安装指南
- (企业)销售货运代理,国内外运输及代理服务费
- ubuntu 下minicom的安装及使用