Qt 多线程用法

文章目录

  • 开发平台
  • [QThread 类 + moveToThread](#QThread 类 + moveToThread)
  • [QtConcurrent::run + QFutureWatcher](#QtConcurrent::run + QFutureWatcher)
  • [QThreadPool + QRunnable](#QThreadPool + QRunnable)

开发平台

项目 说明
OS win10 x64
Qt 6.6
compiler msvc2022
构建工具 cmake

QThread 类 + moveToThread

写一个简单的例子吧,比较容易理解,方便入门. 也可以看出这种方式,对于线程的开销会比较大,但可以自己设置外部的 线程对象, 以达到复用或者减少开销的目的,但不如用线程池来的直接

cpp 复制代码
#include <QApplication>
#include <QThread>
#include <QtConcurrent>


class MyWork : public QObject
{
    Q_OBJECT
public:
    MyWork() {
        this->moveToThread(&thread);
        thread.start();

        connect(this,&MyWork::startSignal,this,&MyWork::run);
        connect(&thread,&QThread::finished,this,[]{
            qDebug() << "Thread::finished";
        });
        connect(&thread,&QThread::destroyed,qApp,[]{
            qDebug() << "Thread::destroyed";
        });
    }

    ~MyWork(){
        if(thread.isRunning())
            thread.terminate();
        qDebug() << "~MyWork()";
    }

    void start() {
        emit startSignal();
    }

    void stop(){
        running = false;
        if(thread.isRunning())
            thread.quit();
    }

    void run() {
        static int i = 0;
        while(running) {
            QThread::msleep(1000);
            qDebug() << i++ << ":" << QThread::currentThreadId();
        }
    }

signals:
    void startSignal();
    void stopSignal();


private:
    QThread thread;
    bool running = true;
};



int main(int argc, char** argv) {

    QApplication a(argc,argv);
    qDebug() << QThread::currentThreadId();
    MyWork mw;
    mw.start();
    QTimer::singleShot(3000,[&mw]{
        mw.stop();
    });

    QTimer::singleShot(4000,qApp, SLOT(quit()) );
    return a.exec();
}

#include "main.moc"  // 这一句很重要,因为是写在main.cpp里面的,注意编译器的输出提示

QtConcurrent::run + QFutureWatcher

在 Qt 6 中, QtConcurrent::run 的函数原型中,已经没有 对象指针,即调用成员函数的时候, 要么使用 Lambda 对象 ,要么使用 std::bind 方法

这种方式感觉比较方便,但实际应用起来没有那么美好,属于后期为了改善效率,匆忙添加的手段

cpp 复制代码
#include <QApplication>
#include <QThread>
#include <QTimer>
#include <qDebug>
#include <QtConcurrent>

class MyWork  {
    QFutureWatcher<void> w;
    bool isRun = false;
public:
    MyWork() {
        qDebug() << " MyWork()";
        QObject::connect(&w, &QFutureWatcher<void>::finished, &w, []{
            qDebug() << "QFutureWatcher<void>::finished";
        });
    }


    ~MyWork(){
        qDebug() << " ~MyWork()";
    }

    void start() {
        isRun = true;

        auto fun =  std::bind(&MyWork::run, this );
        auto ret = QtConcurrent::run( fun );

        // auto ret = QtConcurrent::run([this]{
        //     run();
        // });

        w.setFuture(ret);
    }
    void stop(){
        isRun = false;
    }

    void run() {
        int i = 0;
        while(isRun) {
            QThread::msleep(1000);
            qDebug() << i++ << ":" << QThread::currentThreadId();
        }
    }
};
int main(int argc, char** argv) {

    QApplication a(argc,argv);
    qDebug() << ":" << QThread::currentThreadId();

    MyWork mw;
    mw.start();

    QTimer::singleShot(3000, [&mw]{
        mw.stop();
    });
    QTimer::singleShot(5000, []{
        qDebug() << "qApp->quit();";
        qApp->quit();
    });

    return a.exec();
}

QThreadPool + QRunnable

继承 QRunnable, 重写 run

QThreadPool::globalInstance()->start(this);

清晰明了, QThreadPool 提供了 线程的管理,不需要自己去写一个管理器

CPP 复制代码
#include <QApplication>
#include <QtConcurrent>

class MyWork :public QRunnable {
    bool isRun = false;
public:
    MyWork() {
        // setAutoDelete(false);
        qDebug() << " MyWork()";
    }

    ~MyWork(){
        qDebug() << " ~MyWork()";

    }

    void start(){
        isRun = true;
        QThreadPool::globalInstance()->start(this);
    }

    void stop(){
        isRun = false;
    }

    void run() {
        int i = 0;
        while(isRun) {
            QThread::msleep(1000);
            qDebug() << i++ << ":" << QThread::currentThreadId();
        }
    }
};
int main(int argc, char** argv) {

    QApplication a(argc,argv);
    qDebug() << ":" << QThread::currentThreadId();

    // MyWork mw ;
    // mw.start();

    MyWork *mw = new MyWork;
    mw->start();


    QTimer::singleShot(3000, [mw]{
        mw->stop();
    });
    QTimer::singleShot(6000, []{
        qApp->quit();
    });

    return a.exec();
}
相关推荐
以卿a41 分钟前
C++ 模板初阶
开发语言·c++
s:1031 小时前
【框架】参考 Spring Security 安全框架设计出,轻量化高可扩展的身份认证与授权架构
java·开发语言
道不尽世间的沧桑2 小时前
第17篇:网络请求与Axios集成
开发语言·前端·javascript
久绊A2 小时前
Python 基本语法的详细解释
开发语言·windows·python
软件黑马王子5 小时前
C#初级教程(4)——流程控制:从基础到实践
开发语言·c#
cpp_learners5 小时前
QT 引入Quazip和Zlib源码工程到项目中,无需编译成库,跨平台,压缩进度
qt·zlib·加密压缩·quazip
闲猫5 小时前
go orm GORM
开发语言·后端·golang
李白同学7 小时前
【C语言】结构体内存对齐问题
c语言·开发语言
黑子哥呢?8 小时前
安装Bash completion解决tab不能补全问题
开发语言·bash
青龙小码农8 小时前
yum报错:bash: /usr/bin/yum: /usr/bin/python: 坏的解释器:没有那个文件或目录
开发语言·python·bash·liunx