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

本文详细介绍了Qt中线程的事件循环,包括如何在线程中启动事件循环,以及QObject如何与事件循环交互。强调了线程安全问题,特别是跨线程访问QObject子类的注意事项,如使用mutex保护数据访问和使用deleteLater()。还阐述了Qt的信号和槽在不同线程间的连接方式,如AutoConnection、DirectConnection等,以及它们的使用场景和潜在风险。

线程的事件循环:

  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()也不会工作。

</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值