Qt篇: 多线程如何创建之moveToThread
继承QThread方式缺点
早期Qt软件版本只能提供继承QThread的方式创建新线程,这是跟面向对象程序设计的早期有关,当时习惯于工程中用继承的方式去扩展系统的功能,那这样创建的线程有什么意义吗?
1、通过QThread继承实现的线程是没有任何意义的;
2、QThread的线程子类仅仅只有受保护的run()函数接口是不同的,其他接口完全是相同的;
3、QThread对应于操作系统中的线程;
4、QThread用于充当一个线程操作的集合;
5、应该提供更灵活的方式去实现线程入口函数;
6、尽量避免重写run函数。
QThread的改进
早期的QThread子类必须重写run()函数,而现代Qt不在是纯虚函数了,类的本身就已经对run()函数进行了默认的实现,启动了事件循环,这就意味着可以利用信号槽的方式去创建新线程。从下面两段代码即可看得出来。
- 早期QThread内部实现代码如下:
class QThread : public QObject
{
// do something...
protected:
virtual void run() = 0;
// do something...
}
- 现代Qt创建新线程的内部实现
class QThread : public QObject
{
Q_OBJECT
// do something...
protected:
virtual void run()
{
(void)exec;
}
// do something...
}
新创建线程方式--信号槽
现代软件提倡通过以组合的方式去替代继承,从而Qt5之后引入新的创建新线程的方式,不再继续通过继承QThread的方式,也是Qt提倡使用的,也就是通过信号槽的方式去启动新的线程,通过moveToThread()的方式去改变当前对象线程的依附性。
1、创建一个业务类继承于QObject;
//! 1、创建一个业务类继承于QObject
class NewThreadCreate : public QObject
2、在类中定义一个槽函数Tmain()作为线程的入口函数;
private slots:
//! 2、在类中定义一个槽函数Tmain()作为线程的入口函数
void Tmain();
3、在类中定义一个QThread对象m_thread;
//! 3、在类中定义一个QThread对象m_thread
QThread m_thread;
4、通过moveToThread()改变当前对象线程的依附性至m_thread;
//! 4、通过moveToThread()改变当前对象线程的依附性至m_thread
moveToThread(&m_thread);
5、连接新线程m_thread的start()信号到Tmain()槽函数。
//! 5、连接新线程m_thread的start()信号到Tmain()槽函数
QObject::connect(&m_thread, &QThread::started, this, &NewThreadCreate::Tmain);
完整示例代码
#ifndef NEWTHREADCREATE_H
#define NEWTHREADCREATE_H
#include <QObject>
#include <QThread>
#include <QDebug>
//! 1、创建一个业务类继承于QObject
class NewThreadCreate : public QObject
{
Q_OBJECT
//! 3、在类中定义一个QThread对象m_thread
QThread m_thread;
public:
NewThreadCreate();
~NewThreadCreate();
void Start();
void Exit(int e);
void Terminate();
private slots:
//! 2、在类中定义一个槽函数Tmain()作为线程的入口函数
void Tmain();
};
#endif // NEWTHREADCREATE_H