Qt的QThread类提供了两种多线程的实现方式,一种是直接继承自QThread,把耗时的操作放在重写的run()函数中去执行,调用start()函数,就开始执行run()函数中的程序,调用stop()结束线程的执行。一般有无限循环的耗时操作会采用这种处理方式,例如:可以在run()函数中进行设备音视频的采集操作。这种方式的应用场景较少,在此就不作为重点讲解了。
重点说一下另一种,采用moveToThread方式实现多线程的方式。创建步骤如下:
- 添加一个类,继承自QObject,例如类名为A
- 在A类中添加槽函数,将耗时的操作放在槽函数中进行处理
- 添加如下代码:
A *a = new A();
QThread *thread = new QThread();
a->moveToThread(thread);
connect(thread, &QThread::finished, a, &QObject::deleteLater);//内存释放时使用的
/*connect(信号发出对象,SIGNAL(信号),a,SLOT(耗时的槽函数));*/ //用来绑定耗时操作触发的信号槽
thread->start();
至此,多线程的创建已经完成。下面说一下线程的退出,直接上代码:
if(nullptr != a)
{
//将除connect(thread, &QThread::finished, a, &QObject::deleteLater)之外的信号绑定全部disconnect掉
}
thread->quit();
thread->wait();
delete thread ;
thread = nullptr;
发现没有,多线程的退出只进行thread的退出和删除,不需要进行A对象的delete操作,这就是connect(thread, &QThread::finished, a, &QObject::deleteLater)这条信号绑定的作用,QThread调用quit()函数,在线程退出时会发送finished信号,触发A对象的deletelater函数,会在不需要A对象时进行内存释放。这也就是不需要主动对A对象进行内存释放的原因。
另外有一点需要说明,对于继承自QThread类,重写run()函数的方式,只有run()函数的实现是在子线程中执行的,类中的其他函数不是。对于moveToThread()的方式,只有通过“connect(信号发出对象,SIGNAL(信号),a,SLOT(耗时的槽函数))”绑定的槽函数是在子线程中执行的,其他函数不是。