依附性
Qt对象的依附性,在Qt编程中,默认情况下,对象依附于创建自身的线程,若TestThread对象t它是在main()函数中创建的,那么t依附于主线程,而槽函数在其所依附的线程中被调用执行,因此,槽函数TestThread_Slot()是在main线程中执行
发送信号的线程 和 接收者所依附的线程。而 slot 函数属于我们在main中创建的对象 thread,即thread依附于主线程
- 队列连接告诉我们:槽函数在接受者所依附线程执行。即 slot 将在主线程执行
- 直接连接告诉我们:槽函数在发送信号的线程执行。信号在那个线程发送呢??不定!
- 自动连接告诉我们:二者不同,等同于队列连接。即 slot 在主线程执行
执行线程
QThread 是用来管理线程的,它所依附的线程和它管理的线程并不是同一个东西。
- QThread 所依附的线程:就是执行 QThread t(0) 或 QThread * t=new QThread(0)
的线程。也就是咱们这儿的主线程 - QThread 管理的线程:就是 run 启动的线程。也就是次线程
因为QThread的对象依附在主线程中,所以Qthread生成对象的slot函数会在主线程中执行,而不是次线程。
除非:
常规使用
- QThread 对象(继承自QThread、不是业务对象)依附到次线程中(通过movetoThread)
- QThread 对象的slot 和信号是直接连接,且信号在次线程中发射
但上两种解决方法都不好,因为QThread不是这么用的,也就是让我们不要继承Qthread以及添加业务层需要的成员和方法。让Qthread保持其容器的特点。
完美使用
定义一个普通的QObject派生类(在其中定义槽函数,以便槽函数在移动后所依附的线程中执行),然后将其对象move到QThread中。
使用信号和槽时根本不用考虑多线程的存在。也不用使用QMutex来进行同步,Qt的事件循环会自己自动处理好这个。
class Dummy:public QObject
class Object:public QObject
QThread thread;
Object obj;
Dummy dummy;
obj.moveToThread(&thread); //将obj所依赖的线程移到thread(管理的次线程)中
//槽函数将在次线程中运行,即和Object同一个线程
QObject::connect(&dummy, SIGNAL(sig()), &obj, SLOT(slot()));
thread.start();