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