QtConcurrent應用解析

目錄

對比傳統線程

1.?QtConcurrent::run()?—— 異步運行函數

2.QtConcurrent::mapped()?—— 并行轉換

3.?QtConcurrent::filter()?—— 并行過濾

4.?QtConcurrent::run()?+?QFutureWatcher?—— UI 異步更新

5.線程池配置

QtConcurrent 是 Qt 框架提供的一個 高級并發編程模塊,它封裝了多線程操作,使得開發者可以在 不直接接觸低級線程原語(如 QThread、互斥鎖等) 的前提下,輕松實現并行計算。它基于 線程池(QThreadPool)模板函數,支持異步執行任務、并行算法(如 map、filter、reduce)等

對比傳統線程

特性QThreadQtConcurrent
抽象層級低(需管理線程生命周期)高(自動線程池管理)
代碼復雜度高(需繼承/重寫run)低(函數式編程)
適用場景長期后臺任務短期并行數據處理

通過 QtConcurrent 可顯著減少并發代碼量,典型性能提升場景包括:大數據集轉換(提速 3-8 倍,取決于 CPU 核心數)、批量文件處理等。建議結合?QFutureWatcher?實現進度反饋,提升用戶體驗。

| 模塊 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | 作用 ? ? ? ? ? ? ? ? ? ? ? ?|
| ---------------------------------------- | ------------------------- |
| `QtConcurrent::run()` ? ? ? ? ? ? ? ? ? ?| 在后臺線程中異步運行函數 ? ? ? ? ? ? ?|
| `QtConcurrent::map()` ? ? ? ? ? ? ? ? ? ?| 對容器中的每個元素并行應用函數 ? ? ? ? ? |
| `QtConcurrent::mapped()` ? ? ? ? ? ? ? ? | 并行轉換容器,返回新容器 ? ? ? ? ? ? ?|
| `QtConcurrent::filter()` ? ? ? ? ? ? ? ? | 并行過濾容器元素 ? ? ? ? ? ? ? ? ?|
| `QtConcurrent::filtered()` ? ? ? ? ? ? ? | 并行過濾并返回新容器 ? ? ? ? ? ? ? ?|
| `QtConcurrent::run()` + `QFutureWatcher` | 實現異步任務 + UI 通知 ? ? ? ? ? ?|
| `QFuture<T>` ? ? ? ? ? ? ? ? ? ? ? ? ? ? | 表示異步計算的結果 ? ? ? ? ? ? ? ? |
| `QFutureWatcher<T>` ? ? ? ? ? ? ? ? ? ? ?| 監聽 QFuture 的完成信號,用于 UI 更新 |


1.?QtConcurrent::run()?—— 異步運行函數

auto future = QtConcurrent::run([]() {// 耗時操作return 42;
});
int result = future.result(); // 阻塞等待結果
  • 支持普通函數、lambda、成員函數。

  • 返回 QFuture<T>,可用 QFutureWatcher 監聽完成。

2.QtConcurrent::mapped()?—— 并行轉換

QList<int> input = {1, 2, 3, 4};
auto future = QtConcurrent::mapped(input, [](int val) {return val * val;
});
QList<int> result = future.results(); // {1, 4, 9, 16}
  • 不修改原容器,返回新容器。

  • 自動并行處理,線程數由 QThreadPool 控制。

3.?QtConcurrent::filter()?—— 并行過濾

QList<int> input = {1, 2, 3, 4, 5};
auto future = QtConcurrent::filtered(input, [](int val) {return val % 2 == 0;
});
QList<int> result = future.results(); // {2, 4}

4.?QtConcurrent::run()?+?QFutureWatcher?—— UI 異步更新

QFutureWatcher<int> *watcher = new QFutureWatcher<int>(this);
connect(watcher, &QFutureWatcher<int>::finished, this, [watcher]() {int result = watcher->result();qDebug() << "Result:" << result;
});QFuture<int> future = QtConcurrent::run([]() {QThread::sleep(2);return 42;
});
watcher->setFuture(future);

5.線程池配置

QtConcurrent 默認使用全局線程池

#include <QApplication>
#include <QPlainTextEdit>
#include <QFutureWatcher>
#include <QtConcurrent>
#include <QThread>
#include <QThreadPool>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDateTime>/* 模擬耗時任務:把輸入字符串重復 n 次,中間 sleep 模擬 1 s 工作量 */
static QString heavyWork(const QString &in, int n)
{QString out;for (int i = 0; i < n; ++i) {out += in + ' ';QThread::msleep(200);          // 讓任務跑慢點,方便觀察并發}// 打印當前線程 ID,驗證線程池復用qDebug() << "[heavyWork]" << in << "thread =" << QThread::currentThread();return out.trimmed();
}class Demo : public QWidget
{Q_OBJECT
public:Demo(QWidget *parent = nullptr) : QWidget(parent){setWindowTitle("QtConcurrent 默認全局線程池示例");auto *lay = new QVBoxLayout(this);btn.setText("開始 3 個并發任務");lay->addWidget(&btn);log.setReadOnly(true);lay->addWidget(&log);/* 1. 修改全局線程池容量(僅用于演示) */QThreadPool::globalInstance()->setMaxThreadCount(2);log.appendPlainText(QString("全局線程池 maxThreadCount = %1").arg(QThreadPool::globalInstance()->maxThreadCount()));connect(&btn, &QPushButton::clicked, this, &Demo::startTasks);}private slots:void startTasks(){btn.setEnabled(false);log.appendPlainText("--- 任務已提交 ---");/* 2. 提交 3 個任務,全部進入**同一個**全局線程池 */for (int i = 0; i < 3; ++i) {auto *watcher = new QFutureWatcher<QString>(this);/* 任務完成后把結果打印到日志 */connect(watcher, &QFutureWatcher<QString>::finished,this, [this, watcher]() {log.appendPlainText(QString("[finished] %1").arg(watcher->result()));watcher->deleteLater();});/* 3. 使用 QtConcurrent::run() —— 不指定線程池,即走全局線程池 */QFuture<QString> future =QtConcurrent::run(heavyWork, QString("Task%1").arg(i + 1), 5);watcher->setFuture(future);}log.appendPlainText("(所有任務已提交,線程池自動調度)");}private:QPushButton btn;QPlainTextEdit log;
};#include "main.moc"int main(int argc, char *argv[])
{QApplication a(argc, argv);Demo w;w.resize(500, 350);w.show();return a.exec();
}/*
全局線程池 maxThreadCount = 2
--- 任務已提交 ---
(所有任務已提交,線程池自動調度)
[heavyWork] "Task1" thread = QThread(0x1e4e9f0, name = "Thread (pooled)")
[heavyWork] "Task2" thread = QThread(0x1e4ea90, name = "Thread (pooled)")
[heavyWork] "Task3" thread = QThread(0x1e4e9f0, name = "Thread (pooled)")
[finished] "Task1 Task1 Task1 Task1 Task1"
[finished] "Task2 Task2 Task2 Task2 Task2"
[finished] "Task3 Task3 Task3 Task3 Task3"
*/

實例:并行計算圖片縮略圖

QList<QString> imagePaths = ...;
auto future = QtConcurrent::mapped(imagePaths, [](const QString &path) {QImage image(path);return image.scaled(128, 128);
});QFutureWatcher<QImage> *watcher = new QFutureWatcher<QImage>(this);
connect(watcher, &QFutureWatcher<QImage>::resultReadyAt, this, [watcher](int index) {QImage thumb = watcher->resultAt(index);// 顯示縮略圖
});
watcher->setFuture(future);

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

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

相關文章

大疆圖傳十公里原理:無人機圖傳技術解析

大疆圖傳系統的核心在于把發射端的能量、機載接收的靈敏度、以及環境中的衰減因素&#xff0c;進行科學的預算與動態的修正。簡單的說&#xff0c;就是通過精準的鏈路預算來確保在最壞環境下仍有可用的信號空間。發射功率、天線增益、空中與地面的路徑損耗、接收端的噪聲底線等…

jmeter 帶函數壓測腳本

包含時間戳獲取、md5值計算、隨機字符串獲取<?xml version"1.0" encoding"UTF-8"?> <jmeterTestPlan version"1.2" properties"5.0" jmeter"5.6.3"><hashTree><TestPlan guiclass"TestPlanGui&…

鴻蒙app日志存儲

app的pid獲取 import process from @ohos.process;@Entry @Component struct MainAbility {aboutToAppear(): void {console.log(this.TAG,"pid: "+process.pid)}} 獲取本應用日志 在Android中可以使用logcat --pid xxxx 獲取特定進程xxxx的打印日志 在鴻蒙中也有…

02.【Linux系統編程】Linux權限(root超級用戶和普通用戶、創建普通用戶、sudo短暫提權、權限概念、權限修改、粘滯位)

目錄 1. root超級用戶和普通用戶 2. 創建普通用戶、密碼設置、切換用戶 3. sudo短暫提權&#xff08;給普通用戶添加sudo權限&#xff09; 4. 權限 4.1 是什么 4.2 為什么有權限&#xff1f;&#xff08;權限 角色 目標屬性&#xff09; 4.2.1 角色 4.2.2 目標屬性 …

阿里云可觀測 2025 年 8 月產品動態

本月可觀測熱文回顧 文章一覽&#xff1a; 零代碼改造&#xff01;LoongSuite AI 采集套件觀測實戰 性能瓶頸定位更快更準&#xff1a;ARMS 持續剖析能力升級解析 不只是告警&#xff1a;用阿里云可觀測 MCP 實現 AK 高效安全審計 金蝶云?星辰基于 SLS 構建穩定高效可觀測…

綠蟲零碳助手:通過電費推算用電量,確認光伏裝機規模

在光伏項目開發前期&#xff0c;精準掌握用電需求與合理確定裝機規模是關鍵環節。前者決定光伏系統需滿足的用電基數&#xff0c;后者影響項目投資成本與發電收益匹配度。通過電費數據推算實際用電量&#xff0c;再結合專業工具計算光伏裝機參數&#xff0c;可有效降低項目規劃…

融智學:構建AI時代學術的新范式

融智學&#xff1a;構建AI時代學術新范式摘要&#xff1a;鄒曉輝提出的融智學為現代學術體系困境提供系統性解決方案&#xff0c;通過"問題與價值驅動"的新范式取代傳統"發表驅動"模式。該體系包含三大核心&#xff1a;哲學基礎&#xff08;唯文主義、信息…

【JavaEE初階】-- JVM

文章目錄1. JVM運行流程2. Java運行時數據區2.1 方法區&#xff08;內存共享&#xff09;2.2 堆&#xff08;內存共享&#xff09;2.3 Java虛擬機棧&#xff08;線程私有&#xff09;2.4 本地方法棧&#xff08;線程私有&#xff09;2.5 程序計數器&#xff08;線程私有&#x…

第十四屆藍橋杯青少組C++選拔賽[2023.1.15]第二部分編程題(4 、移動石子)

參考程序1&#xff1a;#include <bits/stdc.h> using namespace std; int main() {int N;cin >> N;vector<int> stones(N);int sum 0;for (int i 0; i < N; i) {cin >> stones[i];sum stones[i];}int target sum / N; // 每個籃子的平均值int a…

Spring Boot 的注解是如何生效的

在 Spring 中&#xff0c;Configuration、ComponentScan、Bean、Import 等注解的掃描、解析和 BeanDefinition 注冊是一個分層處理的過程。下面我們以 Configuration 類為例&#xff0c;結合代碼流程詳細說明其從掃描到注冊的完整邏輯。 1. 整體流程概覽 以下是核心步驟的流程圖…

Django REST Framework響應類Response詳解

概述 Response 類是一個智能的 HTTP 響應類&#xff0c;能夠根據客戶端請求的內容類型&#xff08;Content-Type&#xff09;自動將數據渲染成合適的格式&#xff08;JSON、XML、HTML等&#xff09;。 基本用法 from rest_framework.response import Response# 最簡單的用法 de…

# 小程序 Web 登錄流程完整解析

登錄流程完整小白解析&#xff08;小程序 & Web&#xff09; 在開發中&#xff0c;登錄是每個系統最基礎的功能。為了讓小白也能理解&#xff0c;我們用通俗類比和流程講解 小程序登錄、Web 登錄、Token 刷新、安全存儲等整個過程。1?? 小程序登錄流程&#xff08;小白理…

安裝vcenter6.7 第二階段安裝很慢 或卡在50%

DNS、FQDN配置的問題采用VCSA安裝vCenter時&#xff0c;第一步安裝還算順利&#xff0c;第二步就會安裝失敗&#xff0c;而且還特別慢&#xff0c;這是因為部署時需要DNS服務器&#xff0c;下面就是不采用DNS服務器的部署方案。第一步&#xff1a;正常安裝&#xff0c;DNS就寫本…

第十六屆藍橋杯軟件賽 C 組省賽 C++ 題解

大家好&#xff0c;今天是 2025 年 9 月 11 日&#xff0c;我來給大家寫一篇關于第十六屆藍橋杯軟件賽 C 組省賽的C 題解&#xff0c;希望對大家有所幫助&#xff01;&#xff01;&#xff01; 創作不易&#xff0c;別忘了一鍵三連 題目一&#xff1a;數位倍數 題目鏈接&…

項目幫助文檔的實現

項目幫助文檔的實現 代碼如下&#xff1a; #ifndef __M_HELPER_H__ #define __M_HELPER_H__ #include <iostream> #include <fstream> #include <string> #include <vector> #include <sqlite3.h> #include <random> #include <sstream…

python逆向-逆向pyinstaller打包的exe程序反編譯獲取源代碼

python逆向-逆向pyinstaller打包的exe程序反編譯獲取源代碼 Pyinstaller pyinstaller 是一個用于將 Python 程序打包成獨立可執行文件的工具&#xff0c;能夠在沒有 Python 解釋器的情況下運行。 Python 腳本轉換為 Windows、macOS 和 Linux 操作系統上的可執行文件。 把Python…

【SQL】-- sql having 和 where 的 區別

HAVING 和 WHERE 都是用來篩選數據的&#xff0c;但它們的應用場景有所不同。WHERE&#xff1a;用于篩選行數據&#xff0c;通常在 FROM 子句之后執行。它在分組操作 (GROUP BY) 之前應用&#xff0c;用來篩選出符合條件的記錄。示例&#xff1a;SELECT name, age FROM employe…

MySQL,SQL Server,PostgreSQL三種數據庫各自的優缺點,分別適用哪些場景

MySQL的優缺點及適用場景優點開源免費&#xff0c;社區版可商用&#xff0c;成本低。輕量級&#xff0c;安裝配置簡單&#xff0c;適合中小型項目。讀寫性能優異&#xff0c;尤其在OLTP&#xff08;在線事務處理&#xff09;場景下表現突出。支持主從復制、分片等擴展方案&…

Java 類加載機制雙親委派與自定義類加載器

我們來深入解析 Java 類加載機制。這是理解 Java 應用如何運行、如何實現插件化、以及解決一些依賴沖突問題的關鍵。一、核心概念&#xff1a;類加載過程一個類型&#xff08;包括類和接口&#xff09;從被加載到虛擬機內存開始&#xff0c;到卸載出內存為止&#xff0c;它的整…

Kaggle項目實踐——Titanic: Machine Learning from Disaster

泰坦尼克號沉船事件是機器學習領域最經典的入門項目之一。Kaggle 上的 Titanic: Machine Learning from Disaster 競賽&#xff0c;被無數人稱為“機器學習的 Hello World”。 一、數據導入與清洗&#xff1a;讓數據從 “雜亂” 變 “干凈” 機器學習模型就像 “挑食的孩子”…