qt多線程使用方式

有5個方式:可以參考這個博客:Qt 中開啟線程的五種方式_qt 線程_lucky-billy的博客-CSDN博客

注:為了實現更加靈活的線程管理(因為這5種都有一些不方便之處:QThread需要子類化且不能傳參,moveToThread不能傳參且只能移入一個對象而不是一個函數,QThreadPool 需要子類化QRunnable且只能啟動一個對象,QtConcurrent支持傳參但是不能管理它,std::thread能夠傳入函數以及給定實參但是不是qt方式了),我自己實現了一個更好用的線程管理類(支持指定一個函數,同時指定傳入的實參,而且能管理該線程例如隨時終止等),看我這個博客:?qt自己實現方便的線程管理類_我是標同學的博客-CSDN博客

接下來,講解這5種方式情況:?

1. 繼承 QThread 重寫 run 函數

class Thread : public QThread
{
? ? Q_OBJECT
public:
?? ?virtual void run() override;
}
優點:構造使用方式簡單,所有操作都放在run()方法里面。而且可以隨時停止,因為這是以線程對象形式存在,我們可以對其進行各種管理。
缺點:不夠靈活,只能運行run()里面的程序。此外,傳入的函數不能同時給參數,只能另外一個函數設置其成員變量,run函數里讀取該成員變量。

2. 繼承 QObject 調用 moveToThread

QThread th;
Test test;
test.moveToThread(&th);
優點:使用簡單,可以使用信號槽通信,很靈活。
缺點:每次都要創建線程,帶來不必要資源開支。而且是整個對象給弄進去,也挺重的。

3. 繼承 QRunnable 重新 run 函數,結合 QThreadPool 實現線程池

我們使用線程的時候就去創建一個線程,這樣實現起來非常簡便,但是就會有一個問題:如果并發的線程數量很多,并且每個線程都是執行一個時間很短的任務就結束了,這樣頻繁創建線程就會大大降低系統的效率,因為頻繁創建線程和銷毀線程需要時間。

還有一個問題需要注意一下,QThread 是集成自 QObject 的,我們通常會使用信號槽與外界進行通信。而 QRunnable 并不是繼承自 QObject 類的,所以他無法使用信號槽機制進行通信。這里推薦兩種方法,一個是使用 QMetaObject::invokeMethod()函數。另一個是使用多重繼承的方法,自定義類需要同時繼承自 QRunnable 和 QObject

每個Qt應用程序都有一個全局 QThreadPool 對象,可以通過調用 globalInstance() 來訪問它。==也可以單獨創建一個?QThreadPool?對象使用。

class BPrint : public QRunnable
{
?? ?void run()
?? ?{
?? ? ? ?for ( int count = 0; count < 5; ++count )
?? ? ? ?{
?? ??? ??? ?qDebug() << QThread::currentThread();
?? ??? ??? ?QThread::msleep(1000);
?? ? ? ?}
?? ?}
};

一般情況下,我們不需要在 Qt 程序中創建線程池對象,**直接使用 Qt 為每個應用程序提供的線程池全局對象即可。得到線程池對象之后,調用 start() 方法**就可以將一個任務添加到線程池中,這個任務就可以被線程池內部的線程池處理掉了,使用線程池比自己創建線程的這種多種多線程方式更加簡單和易于維護。
?

4. 使用 C++ 11 中的 std::thread

#include <thread>
void threadfun1()
{
? ? std::cout << "threadfun1 - 1\r\n" << std::endl;
? ? std::this_thread::sleep_for(std::chrono::seconds(1));
? ? std::cout << "threadfun1 - 2" << std::endl;
}

void threadfun2(int iParam, std::string sParam)
{
? ? std::cout << "threadfun2 - 1" << std::endl;
? ? std::this_thread::sleep_for(std::chrono::seconds(5));
? ? std::cout << "threadfun2 - 2" << std::endl;
}

int main()
{
? ? std::thread t1(threadfun1);
? ? std::thread t2(threadfun2, 10, "abc");
? ? t1.join();?? ??? ?// 等待線程 t1 執行完畢
? ? std::cout << "join" << std::endl;
? ? t2.detach();?? ?// 將線程 t2 與主線程分離
? ? std::cout << "detach" << std::endl;
}
t1.join() 會等待t1線程退出后才繼續往下執行t2.detach() 并不會等待,detach字符輸出后,主函數退出,threadfun2還未執行完成,但是在主線程退出后,t2的線程也被已經被強退出

5. Qt QtConcurrent 之 Run 函數

簡單來說,QtConcurrent::run() 函數會在一個單獨的線程中執行,并且該線程取自全局 QThreadPool,該函數的返回值通過 QFuture API 提供。

// 需要傳遞的參數,則跟在函數名之后,依次加入 QFuture<void> future = QtConcurrent::run(FuncWithArguments, integer, string);

...

QString result = future.result();

需要注意的是:
1)該函數可能不會立即運行; 函數只有在線程可用時才會運行
2)通過 QtConcurrent::run() 返回的 QFuture 不支持取消、暫停,返回的 QFuture 只能用于查詢函數的運行/完成狀態和返回值
3) Qt Concurrent 已經從 QtCore 中移除并成為了一個獨立的模塊,所以想要使用 QtConcurrent 需要在 pro 文件中導入模塊:
QT += concurrent
?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/34977.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/34977.shtml
英文地址,請注明出處:http://en.pswp.cn/news/34977.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【leetcode】459. 重復的子字符串(easy)

給定一個非空的字符串 s &#xff0c;檢查是否可以通過由它的一個子串重復多次構成。 示例 1: 輸入: s “abab” 輸出: true 解釋: 可由子串 “ab” 重復兩次構成。 示例 2: 輸入: s “aba” 輸出: false 示例 3: 輸入: s “abcabcabcabc” 輸出: true 解釋: 可由子串 “ab…

ChatGPT等人工智能編寫文章的內容今后將成為常態

BuzzFeed股價上漲200%可能標志著“轉向人工智能”媒體趨勢的開始。 周四&#xff0c;一份內部備忘錄被華爾街日報透露BuzzFeed正計劃使用ChatGPT聊天機器人-風格文本合成技術來自OpenAI&#xff0c;用于創建個性化盤問和將來可能的其他內容。消息傳出后&#xff0c;BuzzFeed的…

ubuntu 20.04 RK3568網絡的優先級設置

1、背景 硬件使用RK3568 CPU&#xff0c;操作系統采用ubuntu 20.04 Lxqt桌面的版本。硬件上具有一個有線以太網卡&#xff0c;一個wifi網卡&#xff0c;一個5G網卡。由于操作系統默認的網絡優先級為有線網卡的最高&#xff0c;5G網卡次之。在一個業務應用中需要5G網卡的連接外…

文本三劍客之grep命令和awk命令 1.0 版本

grep awk 1.grep命令1.1 基本格式1.2 常用選項 2.awk命令2.1 awk工作原理2.2 awk命令格式2.3 awk常用內置變量 1.grep命令 1.1 基本格式 grep [選項]… 查找條件 目標文件1.2 常用選項 選項功能 -m [ x ]匹配x次 后停止,x為具體數字-v取反 -i忽略字符大小寫 -n顯示匹配的 …

Dynamic CRM開發 - 實體介紹

實體簡介 在CRM中,實體(Entity)是數據的基本載體,也是構建業務邏輯網絡的基礎節點。 實體可以理解為數據庫中的一張表(實體中的字段對應數據庫表的字段),比如創建一個實體存儲客戶信息,創建一個實體存儲產品信息,產品實體里可以創建一個查找類型的字段(類似表的外鍵)…

【Express.js】集成RabbitMQ

集成RabbitMQ 本節我們介紹在 express.js 中集成 rabbitmq. RabbitMQ 是一個消息隊列中間件&#xff0c;常用于請求削峰&#xff0c;事務的隊列處理&#xff0c;事件訂閱機制的實現等。 準備工作 創建一個 express.js 項目&#xff08;本文基于evp-express-cli&#xff09;…

【三維編輯】Seal-3D:基于NeRF的交互式像素級編輯

文章目錄 摘要一、引言二、方法2.1.基于nerf的編輯問題概述2.2.編輯指導生成2.3.即時預覽的兩階段學生訓練 三、實驗四、代碼總結 項目主頁: https://windingwind.github.io/seal-3d/ 代碼&#xff1a;https://github.com/windingwind/seal-3d/ 論文: https://arxiv.org/pdf/23…

創建一個Spring Boot項目

安裝所需軟件&#xff1a;首先確保你的計算機上已經安裝了Java JDK和Maven構建工具。你可以從官方網站下載并按照說明進行安裝。 創建一個新的Spring Boot項目&#xff1a;在命令行或終端中使用Maven命令創建一個新的Spring Boot項目。執行以下命令&#xff1a;mvn archetype:…

阿里云輕量應用服務器_2核4G4M_2核2G3M_性能測評

阿里云輕量應用服務器2核2G3M帶寬108元一年&#xff0c;系統盤為50GB高效云盤&#xff1b;輕量服務器2核4G4M帶寬&#xff0c;60GB高效云盤297.98元12個月。目前輕量應用服務器只有2核2G和2核4G有活動&#xff0c;阿里云百科分享阿里云輕量應用服務器入口&#xff1a; 目錄 阿…

【Qt高階】老Qt都不一定清楚的“QObject線程親和性”【2023.08.13】

老Qt都不一定清楚的“線程親和性” 與題目無關 感覺自己還挺2&#xff0c;有粉絲點了那個契約者會給up發個鼓勵的話&#xff0c;我還以為是人私信發的&#xff0c;都挨個感謝了&#xff0c;后來才意識到是系統自動發的&#x1f623;&#x1f623;&#x1f623;。 自上上期視頻對…

Three.js陰影

目錄 Three.js入門 Three.js光源 Three.js陰影 Three.js紋理貼圖 使用燈光后&#xff0c;場景中就會產生陰影。物體的背面確實在黑暗中&#xff0c;這稱為核心陰影&#xff08;core shadow&#xff09;。我們缺少的是落下的陰影&#xff08;drop shadow&#xff09;&#…

【數據結構】——棧、隊列的相關習題

目錄 題型一&#xff08;棧與隊列的基本概念&#xff09;題型二&#xff08;棧與隊列的綜合&#xff09;題型三&#xff08;循環隊列的判空與判滿&#xff09;題型四&#xff08;循環鏈表表示隊列&#xff09;題型五&#xff08;循環隊列的存儲&#xff09;題型六&#xff08;循…

一文揭秘餓了么跨端技術的演進、實踐與落地

跨端技術背景與演進歷程 跨端&#xff0c;究竟跨的是哪些端&#xff1f; 自 90 年的萬維網出現&#xff0c;而后的三十多年&#xff0c;我們依次經歷了 PC 時代、移動時代&#xff0c;以及現在的萬物互聯&#xff08;的 IoT &#xff09;時代&#xff0c;繁榮的背后&#xff…

【Apollo】Apollo-ros版本架構學習與源碼分析

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 這篇文章主要介紹Apollo-ros版本架構學習與源碼分析。 無專精則不能成&#xff0c;無涉獵則不能通。——梁啟超 歡迎來到我的博客&#xff0c;一起學習&#xff0c;共同進步。 喜歡的朋友可以關注一下&a…

微信小程序如何自定義分享卡片文案和圖片

微信小程序提供了onShareAppMessage方法&#xff0c;專門用來監聽用戶點擊頁面內轉發按鈕&#xff08;button 組件 open-type"share"&#xff09;或右上角菜單“轉發”按鈕的行為&#xff0c;并自定義轉發內容。 > 注意&#xff1a;只有定義了此事件處理函數&…

Android studio 設置安卓手機

參考這個鏈接 ghttps://developer.android.com/studio/debug/dev-options 列出常用手機的設置&#xff0c;但是我的手機不在此列 Google Pixel Settings > About phone > Build number Samsung Galaxy S8 and later Settings > About phone > Software informa…

git: ‘lfs‘ is not a git command. see ‘git --help‘

在克隆hugging face里面的項目文件的時候&#xff0c;需要用到git lfs&#xff0c;本文介紹安裝git lfs方法 在Ubuntu下 curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash sudo apt-get install git-lfs在Windows下 到這個鏈…

解決GitHub的速度很慢的幾種方式

1. GitHub 鏡像訪問 這里提供兩個最常用的鏡像地址&#xff1a; https://hub.njuu.cf/search https://www.gitclone.com/gogs/search/clonesearch 也就是說上面的鏡像就是一個克隆版的 GitHub&#xff0c;你可以訪問上面的鏡像網站&#xff0c;網站的內容跟 GitHub 是完整同步…

期權定價模型系列【4】—期權組合的Delta-Gamma-Vega中性

期權組合的Delta-Gamma-Vega中性 期權組合構建時往往會進行delta中性對沖&#xff0c;在進行中性對沖后&#xff0c;期權組合的delta敞口為0&#xff0c;此時期權組合仍然存在gamma與vega敞口。因此研究期權組合的delta-gamma-vega敞口中性是有必要的。 本文旨在對delta-gamma-…

關于新手學習STM32開發應該如何入門?

對于新手來說&#xff0c;學習STM32開發可能會感到困惑&#xff0c;尤其是在拿到開發板后該如何入門。在這里有嵌入式學習路線&#xff0c;畢設&#xff0c;各種項目&#xff0c;需要留個6。以下是部分內容概述&#xff1a;硬件介紹&#xff1a;了解STM32開發板的基本硬件組成和…