QT 多线程之继承 QThread

文章目录

  • 1. 概述
  • 2. 方法描述
  • 3. 代码:
  • 4. 运行结果
  • 5. 结语

1. 概述

在 Qt 中,可以使用 QThread 的两种方式来创建和控制线程:继承 QThread 类和使用 QObject::moveToThread() 方法。上一篇介绍了 QObject::moveToThread() 的方法,这一篇我们介绍 继承 QThread 类的方法。

这是一种较为传统的使用 QThread 的方式,可以创建一个继承自 QThread 类的子类,并在子类中实现 run() 方法,在该方法中编写线程执行的代码,然后在主线程中调用 start() 函数来启动子线程。

2. 方法描述

下面是使用继承 QThread 的方式创建线程的示例代码:

class MyThread : public QThread
{
public:
    void run() override
    {
        // 线程执行的代码
        // ...
    }
};

// 创建线程对象
MyThread* thread = new MyThread();

// 启动线程
thread->start();

 
QT 多线程之继承 QThread_第1张图片

 

3. 代码:

首先写 MyThread 类,该类继承于 QThread 类,该类中自定义了信号和槽,并且重写了 run 函数,头文件如下:

//
// MyThread.h
//
#ifndef DEL2_MYTHREAD_H
#define DEL2_MYTHREAD_H

#include 
#include 

class MyThread : public QThread
{
Q_OBJECT

public:
    explicit MyThread(QObject* parent = nullptr);

signals:
    void myThreadSignal(const int);  // 自定义发送的信号

public slots:
    static void myThreadSlot(int);  // 自定义槽函数

protected:
    void run() override ;
};

#endif //DEL2_MYTHREAD_H

mythread.cpp:

#include "mythread.h"

MyThread::MyThread(QObject* parent)
    : QThread(parent)
{
}

//2. 新线程中的 0x4684
void MyThread::run()
{
    qDebug() << __FUNCTION__ << " Thread ID: " << QThread::currentThreadId() << "\n";

    emit myThreadSignal(100);  // 发送结束信号

    exec();
}

//3. 主线程中的  0x5120
void MyThread::myThreadSlot(const int val)
{
    qDebug() << __FUNCTION__ << " Thread ID: " << QThread::currentThreadId() <<  ", val: " << val <<"\n";
}

在 ThreadController 类中实现 MyThread 的调用

#include "threadcontroller.h"

ThreadController::ThreadController(QObject *parent) : QObject(parent)
{
    _myThread = new MyThread ;

    connect(_myThread, &MyThread::myThreadSignal, this, &ThreadController::handleResults);

    // 该线程结束时销毁
    connect(_myThread, &QThread::finished, this, &QObject::deleteLater);

    connect(this, &ThreadController::operate, _myThread, &MyThread::myThreadSlot);

    // 启动该线程
    _myThread->start();

    // 当前线程挂起 3s
    QThread::sleep(3);

    //3. --- 先执行当前槽函数,再执行run中槽函数
    emit operate(99);
}

ThreadController::~ThreadController()
{
    _myThread->quit();
    _myThread->wait();
}

//4. 主线程中的  0x5120
void ThreadController::handleResults(const int result)
{
    qDebug() << __FUNCTION__ << " Thread ID:" << QThread::currentThreadId() << ", last result: " << result;
}

**threadcontroller.h: **

#ifndef THREADCONTROLLER_H
#define THREADCONTROLLER_H

#include 
#include "mythread.h"

class ThreadController : public QObject
{
Q_OBJECT

public:
    explicit ThreadController(QObject *parent = nullptr);

    ~ThreadController() override ;

public slots:
    static void handleResults(int result);  // 处理子线程执行的结果

signals:
    void operate(const int);  // 发送信号,触发线程

private:
    MyThread* _myThread ;

};

#endif // THREADCONTROLLER_H

接下来就是 main 函数,主函数中我们新建一个 Controller 对象,开始执行:

#include 
#include 
#include 
#include "threadcontroller.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << __FUNCTION__ << " Thread ID:" << QThread::currentThreadId() << '\n' ;

    ThreadController c ;

    return a.exec(); // 进入事件循环
}


4. 运行结果

QT 多线程之继承 QThread_第2张图片

 

注意:

  1. 只有 run() 中的才是新线程,其余都是主线程!
  2. QThread::sleep(3); 使用后,当前主线程挂起 3 秒,而子线程中 run() 继续执行,休眠结束后才会运行主线程的槽函数!

5. 结语

子类化 QThread 的方法,就是重写了 QThread 中的 run() 函数,在 run() 函数中定义需要的工作。这样的结果是,我们自定义的子线程调用 start() 函数后,便开始执行 run() 函数。如果在自定义的线程类 MyThread 中定义相关的槽函数,那么这些槽函数不会由子类化的QThread 自身事件循环所执行,而是由该子线程的拥有者(一般都是主线程)来执行。

而 qt 的线程设计不是希望通过继承去实现多线程,而是希望线程也是作为一个对象可以直接使用,也就是 QObject的moveToThread方法

本文也只是初步的学习,没有关注于线程的释放和创建,以及多线程造成的竞态问题~

参考: QT 中的多线程—继承 QThread 篇

你可能感兴趣的:(C/C++,QT,数据结构,qt,c++,开发语言,多线程,QThread)