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();
}
相关推荐
数据小爬虫@2 小时前
深入解析:使用 Python 爬虫获取苏宁商品详情
开发语言·爬虫·python
健胃消食片片片片2 小时前
Python爬虫技术:高效数据收集与深度挖掘
开发语言·爬虫·python
王老师青少年编程3 小时前
gesp(C++五级)(14)洛谷:B4071:[GESP202412 五级] 武器强化
开发语言·c++·算法·gesp·csp·信奥赛
一只小bit4 小时前
C++之初识模版
开发语言·c++
王磊鑫4 小时前
C语言小项目——通讯录
c语言·开发语言
钢铁男儿4 小时前
C# 委托和事件(事件)
开发语言·c#
Ai 编码助手5 小时前
在 Go 语言中如何高效地处理集合
开发语言·后端·golang
喜-喜5 小时前
C# HTTP/HTTPS 请求测试小工具
开发语言·http·c#
ℳ₯㎕ddzོꦿ࿐5 小时前
解决Python 在 Flask 开发模式下定时任务启动两次的问题
开发语言·python·flask
一水鉴天5 小时前
为AI聊天工具添加一个知识系统 之63 详细设计 之4:AI操作系统 之2 智能合约
开发语言·人工智能·python