Qt 多线程用法
2023-12-22 13:49:05
    		开发平台
| 项目 | 说明 | 
|---|---|
| OS | win10 x64 | 
| Qt | 6.6 | 
| compiler | msvc2022 | 
| 构建工具 | cmake | 

QThread 类 + moveToThread
写一个简单的例子吧,比较容易理解,方便入门. 也可以看出这种方式,对于线程的开销会比较大,但可以自己设置外部的 线程对象, 以达到复用或者减少开销的目的,但不如用线程池来的直接
#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 方法
 这种方式感觉比较方便,但实际应用起来没有那么美好,属于后期为了改善效率,匆忙添加的手段
#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 提供了 线程的管理,不需要自己去写一个管理器
#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();
}
    			文章来源:https://blog.csdn.net/hitzsf/article/details/135150485
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
    	本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!