当前位置 博文首页 > 木木木 的博客:Qt开发之路30---4种常用的多线程实现方式

    木木木 的博客:Qt开发之路30---4种常用的多线程实现方式

    作者:[db:作者] 时间:2021-08-20 21:37

    一:继承Qthread

    • 方法: 继承自QThread类,重写run函数,通过start启动线程。此实现方法只有run函数内的代码是运行在子线程内。
    • 例程:
    #ifndef MYTHREAD_H
    #define MYTHREAD_H
    
    #include <QThread>
    
    class MyThread: public QThread
    {
        Q_OBJECT
    
    public:
        MyThread();
        ~MyThread();
    
    protected:
        void run(); //虚函数重构
    
    public:
        void stop();
    
    private:
        bool m_bFlag;
    
    };
    
    #endif // MYTHREAD_H
    
    #include "mythread.h"
    #include <QDebug>
    
    MyThread::MyThread()
    {
    
    }
    
    MyThread::~MyThread()
    {
    
    }
    
    void MyThread::run()
    {
        m_bFlag = true;
        while (m_bFlag) {
            qDebug() << "thread id: "<<QThread::currentThreadId();
            QThread::msleep(100);
        }
    }
    
    void MyThread::stop()
    {
        m_bFlag = false;
    }
    
    
    #include "mythread.h"
    #include <QApplication>
    
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        MyThread *myThread = new MyThread();
    
        myThread->start(); //开启线程
    
    
        return a.exec();
    }
    
    • 特点:
      可以通过信号槽与外界进行通信;
      每次新建一个线程都需要继承QThread类,使用不太方便;

    二:moveToThread

    • 方法:
      创建一个继承QObject的类(myWork),然后new一个Qthread,并把创建的myWork类movetothread到创建好的子线程中,然后start子线程,这样就实现了一个子线程。主线程通过发送信号,调用myWork中的方法,从而实现在子线程中的计算。
    • 例程:
    #ifndef MYWORK_H
    #define MYWORK_H
    
    #include <QObject>
    
    class MyWork : public QObject
    {
        Q_OBJECT
    public:
        explicit MyWork(QObject *parent = 0);
    
    signals:
    
    public slots:
        void doWork();
    };
    
    #endif // MYWORK_H
    
    #include "mywork.h"
    #include <QDebug>
    #include <QThread>
    
    MyWork::MyWork(QObject *parent) : QObject(parent)
    {
    
    }
    
    void MyWork::doWork()
    {
        for(int i = 0; i < 1000; i++){
            qDebug() << "thread id: "<<QThread::currentThreadId();
        }
    
    }
    
    #include "mywork.h"
    #include <QApplication>
    #include <QThread>
    
    
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
    
        MyWork *myWork = new MyWork();
        QThread *myThread = new QThread();
    
        QObject::connect(myThread,SIGNAL(started()),myWork,SLOT(doWork()));
        QObject::connect(myThread,SIGNAL(finished()),myWork,SLOT(deleteLater()));
        QObject::connect(myThread,SIGNAL(finished()),myThread,SLOT(deleteLater()));
    
        myWork->moveToThread(myThread);
        myThread->start();
    
        return a.exec();
    }
    
    
    • 特点:
      moveToThread对比传统子类化Qthread更灵活,仅需要把你想要执行的代码放到槽,movetothread这个object到线程,然后拿一个信号连接到这个槽就可以让这个槽函数在线程里执行。
      轻量级的函数可以用movethread,多个短小精悍能返回快速的线程函数适用 ,无需创建独立线程类,例如你有20个小函数要在线程内做, 全部扔给一个QThread。

    三:QRunnalble的run

    • 方法:
      继承QRunnable。和QThread使用一样。
      重写run函数。
      使用QThreadPool启动线程
    • 例程:
    class Runnable:public QRunnable
    {
           //Q_OBJECT   Qrunnable不是QObject的子类。
    public:
           Runnable();
           ~Runnable();
           void run();
    };
     
     
    Runnable::Runnable():QRunnable()
    {
     
    }
     
    Runnable::~Runnable()
    {
           cout<<"~Runnable()"<<endl;
    }
     
    void Runnable::run()
    {
           cout<<"Runnable::run()thread :"<<QThread::currentThreadId()<<endl;
    }
    int main(int argc, char *argv[])
    {
           QCoreApplication a(argc, argv);
    
           Runnable runObj;
           QThreadPool::globalInstance()->start(&runObj);
           returna.exec();
    }
    
    • 特点:
      无需手动释放资源,QThreadPool启动线程执行完成后会自动释放。
      不能使用信号槽与外界通信。
      适用场景,需要频繁创建线程。

    四:QtConcurrent::run

    • 方法:
      Concurrent是并发的意思,QtConcurrent是一个命名空间。使用QtConcurrent编写的程序会根据可用的处理器内核数自动调整使用的线程数。
      QtConcurrent::run能够方便快捷的将任务丢到子线程中去执行,无需继承任何类,也不需要重写函数,使用非常简单。
      需要注意的是,由于该线程取自全局线程池QThreadPool,函数不能立马执行,需要等待线程可用时才会运行。
      编程过程:
      1、首先在.pro文件中加上以下内容:QT += concurrent
      2、包含头文件#include ,然后就可以使用QtConcurrent了
      QtConcurrent::run(func, QString(“Thread 1”)); fut1.waitForFinished();
    • 例程:
    #include <QApplication>
    #include <QThread>
    #include <QtConcurrent/QtConcurrent>
    
    void myPrint(QString str)
    {
        qDebug()<<str;
    }
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QString str = "123";
        QtConcurrent::run(myPrint,str);
    
        return a.exec();
    }
    
    • 特点:
      简单,快捷

    上一篇:Qt开发之路29—UDP 与 TCP区别(Socket通信)
    下一篇:Qt开发之路31—Qt程序自动打包

    cs