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();
}
相关推荐
小蕾Java8 分钟前
Python详细安装教程(附PyCharm使用)
开发语言·python·pycharm
weixin_3077791314 分钟前
AWS云上ClickHouse数据仓库部署方案详解
开发语言·clickhouse·自动化·云计算·aws
weixin_3077791317 分钟前
使用AWS IAM和Python自动化权限策略分析与导出
开发语言·python·自动化·云计算·aws
惜月_treasure22 分钟前
从零构建私域知识库问答机器人:Python 全栈实战(附完整源码)
开发语言·python·机器人
咯哦哦哦哦36 分钟前
关于QT 打印中文 乱码问题
java·数据库·qt
mark-puls38 分钟前
Qt界面布局利器:QStackedWidget详细用法解析
开发语言·qt
chennn121 小时前
c++相关学习
开发语言·c++·学习
珹洺2 小时前
Java-Spring入门指南(二十二)SSM整合前置基础
java·开发语言·spring
ʚ希希ɞ ྀ2 小时前
用队列实现栈---超全详细解
java·开发语言·数据结构
郝学胜-神的一滴2 小时前
Python中的鸭子类型:理解动态类型的力量
开发语言·python·程序人生·软件工程