QT信号槽机制分析

1.应用于对象之间的通信

2.类似观察者模式(信号发送者->被观察者,信号接收者->观察者)

3.与回调不同:回调:通过一个函数指针链表

                        信号槽:减少耦合,谁先连接先执行谁

4.第5个参数:第5个参数代表在哪个线程

          (1):自动连接(AutoConnection),默认的连接方式,如果信号与槽,也就是发送者与接受者在同一线程,等同于直接连接;如果发送者与接受者处在不同线程,等同于队列连接。

          (2):2)直接连接(DirectConnection),当信号发射时,槽函数立即直接调用。无论槽函数所属对象在哪个线程,槽函数总在发送者所在线程执行,即槽函数和信号发送者在同一线程

          (3):队列连接(QueuedConnection),当控制权回到接受者所在线程的事件循环时,槽函数被调用。槽函数在接受者所在线程执行,即槽函数与信号接受者在同一线程

          (4):定队列连接(BlockingQueuedConnection),槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。

           (5):单一连接(UniqueConnection),这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接

5.槽函数何时执行:

每个线程均有自己的消息事件循环队列

直连方式,是所谓立即执行,就是函数直接调用。

队列方式,不会立即执行,分单/多线程情况:

      a.单线程(发送、接收同一线程):消息放入消息队列。线程进入消息队列时,依次执行队列上消息对应槽函数。

      b.跨线程(发送、接收不同线程):消息放入接收者线程队列。接收者线程运行时(可能阻塞、睡眠、或退出),进入它的消息队列后,依次执行队列上的消息。这也意味着,同一个槽函数不会重入,不用考虑重入互斥访问,因为都在队列上排队等待依次执行(注意不要乱用postEvents函数,后续我们有机会单独讲一讲该问题)。
6.QT多线程变成注意点:

      (1).QT主线程不能阻塞。因为UI在主线程中,阻塞则界面卡死。使用while()QCoreApplication::processEvents(); qapp->processEvents()替换睡眠操作。

      (2).非主线程不能操作UI控件,否则QT崩溃。这也是要分离界面与逻辑的重要原因

      (3).父子QObject对象,必须在同一个线程;不同线程的对象,不能是父子关系。

否则会报错,或者产生未知情况

      (4).官方优先推荐使用moveToThread方式,其次使用继承QThread方式。

      (5).注意槽函数是在线程中执行。如果执行线程睡眠、阻塞,槽函数没有机会执行。如果你的槽函数要快速响应,不要让它在可能阻塞或睡眠的线程中

      (6).要注意volidate修饰共享变量、要注意加锁。不同的锁行为会导致线程不同状态,得根据线程业务状态去考虑用什么锁

      (7).活用慎用processEvents,线程(包括主线程和其它线程)执行很繁重的计算任务中,为防止消息事件一直无机会处理,则在函数中手动调用processEvents,让消息事件有机会更新。界面不会假死。另一方面,槽函数中不可调用processEvents,因为这会导致“中断”当前槽函数,进而去执行消息队列中后续的槽函数,可能会引发同一槽函数重入问题,将编程问题复杂化。
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值