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();
}
相关推荐
凤城老人3 分钟前
C++使用拉玛努金公式计算π的值
开发语言·c++·算法
HAH-HAH2 小时前
【Python 入门】(2)Python 语言基础(变量)
开发语言·python·学习·青少年编程·个人开发·变量·python 语法
递归不收敛3 小时前
一、Java 基础入门:从 0 到 1 认识 Java(详细笔记)
java·开发语言·笔记
zhangfeng11334 小时前
win7 R 4.4.0和RStudio1.25的版本兼容性以及系统区域设置有关 导致Plots绘图面板被禁用,但是单独页面显示
开发语言·人工智能·r语言·生物信息
姓刘的哦4 小时前
Qt中的QWebEngineView
数据库·c++·qt
SundayBear5 小时前
QT零基础入门教程
c++·qt
子午5 小时前
Python的uv包管理工具使用
开发语言·python·uv
HMBBLOVEPDX6 小时前
C++(静态函数)
开发语言·c++
dpxiaolong7 小时前
RK3588 Android12默认移除导航栏
开发语言·python
Pocker_Spades_A7 小时前
Python快速入门专业版(二十九):函数返回值:多返回值、None与函数嵌套调用
服务器·开发语言·python