日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt中使用线程的几种方式及区别

發布時間:2025/1/21 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt中使用线程的几种方式及区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

Qt中有多種創建線程的方式,每一種的應用場景和使用方式都有些區別, 這里主要簡單介紹Qt里面的幾大創建線程的方法,以及使用注意事項。

QThread

使用QThread創建線程是我們最常見的一種方式,步驟如下:

  • 繼承QThread
  • 重寫run()函數
  • 通過start()函數啟動線程

優點:可以通過信號槽與外界進行通信。
缺點:①每次新建一個線程都需要繼承QThread,實現一個新類,使用不太方便。
②要自己進行資源管理,線程釋放和刪除。并且頻繁的創建和釋放會帶來比較大的內存開銷。
適用場景:QThread適用于那些常駐內存的任務。

#include <QThread> #include <QDebug>class MyThread : public QThread {Q_OBJECT protected:void run(){//do somethingqDebug() <<__FUNCTION__ << "id = " << QThread::currentThreadId();QThread::msleep(1000);} }; int main(int argc, char *argv[]) {QApplication a(argc, argv);qDebug() <<__FUNCTION__ << "id = " << QThread::currentThreadId();MyThread * myThread = new MyThread;myThread->start();return a.exec(); }

輸出:

main id = 0x29a4 MyThread::run id = 0x1c2c

QRunnable

前面一篇文章已經詳細介紹了QRunnable的使用方法【文章在這里】。 所以這里就不詳細描述了, 重點講一下優缺點和適用場景。

步驟如下:

  • 繼承QRunnable。和QThread使用一樣, 首先需要將你的線程類繼承于QRunnable。
  • 重寫run函數。還是和QThread一樣,需要重寫run函數,run是一個純虛函數,必須重寫。
  • 使用QThreadPool啟動線程

優點:無需手動釋放資源,QThreadPool啟動線程執行完成后會自動釋放。
缺點:不能使用信號槽與外界通信。
適用場景:QRunnable適用于線程任務量比較大,需要頻繁創建線程。QRunnable能有效減少內存開銷。

具體代碼就不貼了,詳情參見上一篇文章。

moveToThread

moveToThread是在QThread的用法基礎上擴展出來的,它是QObject的接口,相對QThread線程方式來說,moveToThread使用更靈活,不需要繼承QThread,也不用重寫run函數。只需要將一個繼承于QObject的類通過moveToThread移到QThread的一個對象中。
需要注意的是:

  • 只有在槽中執行的操作才是在線程中執行的,所以需要通過連接信號槽的方式來實現
  • 如果object對象存在父對象,不能將其移到子線程中執行。

示例如下:

#include <QObject> #include <QThread>class Command : public QObject {Q_OBJECT public:explicit Command(QObject *parent = nullptr);void sendMessage(const QString &msg);signals:void sigMsg(QString msg);private slots:void onMessage(QString msg);private:QThread * m_pThread = nullptr; }; #include "command.h" #include <QDebug>Command::Command(QObject *parent) :QObject(parent) {m_pThread = new QThread();this->moveToThread(m_pThread);connect(this,&Command::sigMsg,this,&Command::onMessage);m_pThread->start();qDebug()<< __FUNCTION__ << " id = "<< QThread::currentThreadId(); }void Command::sendMessage(const QString &msg) {emit sigMsg(msg); }void Command::onMessage(QString msg) {qDebug()<< __FUNCTION__ << " id = "<< QThread::currentThreadId(); }

調用:

m_pCommand = new Command(); //不能指定父類 m_pCommand->sendMessage("ABC");

輸出:

Command::Command id = 0x4b58 Command::onMessage id = 0x3c84

QtConcurrent::run

有關QtConcurrent::run的使用方法在之前的文章里面有詳細介紹過,在這里,Concurrent是并發的意思,QtConcurrent是一個命名空間,提供了一些高級的 API,使得在編寫多線程的時候,無需使用低級線程原語,如讀寫鎖,等待條件或信號。使用QtConcurrent編寫的程序會根據可用的處理器內核數自動調整使用的線程數。這意味著今后編寫的應用程序將在未來部署在多核系統上時繼續擴展。

QtConcurrent::run能夠方便快捷的將任務丟到子線程中去執行,無需繼承任何類,也不需要重寫函數,使用非常簡單。詳見前面的文章介紹,這里不再贅述。

需要注意的是,由于該線程取自全局線程池QThreadPool,函數不能立馬執行,需要等待線程可用時才會運行。

總結

以上是生活随笔為你收集整理的Qt中使用线程的几种方式及区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。