qt-线程的事件循环和跨线程通信

线程的事件循环:

  1. 每一个线程都可以有它自己的事件循环。初始化线程(GUI线程)使用QCoreApplication::exec()来开启它的事件循环(对于独立的对话框界面程序,也可以使用QDialog::exec()).其他的线程可以使用QThread::exec()来开启一个事件循环。与QCoreApplication相似,QThread提供了一个exit()函数和一个quit()槽。在一个线程中使用事件循环,使得该线程可以使用那些需要事件循环的非GUI类(例如,QTimer、QTcpSocket、QProcess等等)。也使得该线程可以关联任意一个线程的信号到一个指定线程的槽。

QObject与事件循环

  • 如果在一个线程中创建了一个QObject对象,那么这个QObject对象被称为居住在该线程(live in the thread)。发往这个对象的事件由该线程的事件循环进行分派。可以使用QObject::thread()获得该对象所居住的线程。可以使用QObject::moveToThread()来改变对象及其孩子所在的线程(如果该对象有父对象,那么它无法被移动)。
  • 在其他线程(不是拥有该QObject对象的线程)中调用delete来删除(或通过其他方式访问)该QObject对象是不安全的,除非可以确保该对象当前没有在处理事件。可以使用QObject::deleteLater()来代替,这样会发送一个DeferredDelete事件,最终该对象所在线程的事件循环将会获取该事件。默认的,拥有该QObject对象的线程就是创建该QObject对象的线程,只要没有调用过QObject::moveToThread()函数。
  • 如果没有运行事件循环,则事件将不会传送到对象。例如,如果在一个线程中创建了一个QTimer对象,但是从来没有调用exec()函数,那么QTimer将永远不会发射它的timeout()信号。调用deleteLater()也不会工作。

从其他线程中访问QObject子类

  • QObject和它所有的子类都不是线程安全的,这包括了整个事件传递系统。需要注意的是,正在从其他线程中访问一个对象时,事件循环可能正在向这个对象传递事件。
  • 如果调用一个没有在当前线程中的QObject子类的函数,而这个对象有可能会获取事件,那么就必须使用mutex来保护对这个QObject子类的内部数据的所有访问。否则,可能出现崩溃或者其他意外行为。
  • 与其他对象相似,QThread对象居住于创建该对象的线程。在QThread子类中提供槽一般是不安全的,除非使用mutex来保护乘员变量。但是,可以安全地在QThread::run()函数中发射信号,因为信号发射是线程安全的。

跨线程的信号和槽

Qt支持几种信号和槽关联类型:

  1. Auto Connection(默认)。如果信号发射和信号接收的对象在同一个线程,那么执行方式与Direct Connection相同。否则,执行方式与Queued Conection相同。
  2. Direct Connection。信号发射后,槽立即被调用。槽在信号发送者的线程中执行,而接收者并非必须在同一个线程。
  3. Blocking Queued Connection。槽的调用与Queued Connection相同,不同的是当前线程会阻塞直到槽返回。注意:使用这种方式关联在相同线程中的对象时,会引起死锁。
  4. Unique Connection。执行方式与Auto Connection相同。只不过关联是唯一的。
    可以通过向connect()函数传递附加的参数来指定关联类型。注意,如果在接收者线程中有一个事件循环,那么当发送者与接收者在不同的线程中时,使用Direct Connection是不安全的;类似的,调用其他线程中的对象的任何函数也是不安全的,不过,需要明确的是QObject::connect()函数本身是线程安全的。
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值