Qt開發:QtConcurrent介紹和使用

文章目錄

    • 一、QtConcurrent 簡介
    • 二、常用功能分類
      • 2.1 異步運行一個函數(無返回值)
      • 2.2 異步運行一個帶參數的函數(有返回值)
      • 2.3 綁定類成員函數
      • 2.4 容器并行處理(map)
    • 三、線程池控制
    • 四、取消任務
    • 五、典型應用場景
    • 六、完整示例:并發下載圖片

一、QtConcurrent 簡介

QtConcurrent 是 Qt 提供的一個高級并發編程模塊,屬于 QtConcurrent 命名空間,旨在簡化多線程任務的執行。它支持并行執行算法(如 map、filter、reduce),還支持異步任務運行和結果管理,不需要顯式管理 QThread。

模塊介紹
頭文件包含:

#include <QtConcurrent>

模塊依賴:

QT += concurrent

常用功能:
在這里插入圖片描述

二、常用功能分類

2.1 異步運行一個函數(無返回值)

QtConcurrent::run([]() {qDebug() << "后臺線程中執行任務:" << QThread::currentThread();
});

2.2 異步運行一個帶參數的函數(有返回值)

int add(int a, int b) {return a + b;
}QFuture<int> future = QtConcurrent::run(add, 3, 5);// 后續獲取結果
int result = future.result();  // 阻塞直到完成
qDebug() << "結果是:" << result;

2.3 綁定類成員函數

class Worker {
public:int multiply(int x, int y) {return x * y;}
};Worker worker;
QFuture<int> future = QtConcurrent::run(&worker, &Worker::multiply, 4, 6);

2.4 容器并行處理(map)

并發修改容器元素(原地修改)

QList<int> numbers = {1, 2, 3, 4, 5};auto doubleIt = [](int &n) {n *= 2;
};QtConcurrent::map(numbers, doubleIt);// 輸出: 2 4 6 8 10

并發映射容器到新容器(mapped)

QList<int> numbers = {1, 2, 3};auto square = [](int n) {return n * n;
};QList<int> squares = QtConcurrent::mapped(numbers, square).results();
// 輸出: 1 4 9

并發過濾(filtered)

QStringList names = {"Alice", "Bob", "Eve"};auto isShort = [](const QString &name) {return name.length() <= 3;
};QStringList shortNames = QtConcurrent::filtered(names, isShort).results();
// 輸出: Bob, Eve

2.5 使用 QFutureWatcher 監聽結果(推薦與 UI 配合)

QFutureWatcher<QString> *watcher = new QFutureWatcher<QString>(this);connect(watcher, &QFutureWatcher<QString>::finished, this, [=]() {QString result = watcher->result();qDebug() << "計算完成,結果為:" << result;
});QFuture<QString> future = QtConcurrent::run([]() {QThread::sleep(2);return QString("Hello from thread");
});watcher->setFuture(future);

三、線程池控制

QtConcurrent 默認使用全局 QThreadPool,可通過如下方式調整:

QThreadPool::globalInstance()->setMaxThreadCount(8);

或者使用局部線程池:

QThreadPool pool;
QtConcurrent::run(&pool, someFunction);

四、取消任務

可通過 QFuture 中的 cancel() 方法取消任務:

QFuture<void> future = QtConcurrent::run([]{for (int i = 0; i < 100; ++i) {if (QThread::currentThread()->isInterruptionRequested()) {return;}QThread::msleep(100);}
});// 取消任務
future.cancel();

五、典型應用場景

在這里插入圖片描述

六、完整示例:并發下載圖片

效果目標:
在這里插入圖片描述
核心類:ImageDownloader

// ImageDownloader.h#ifndef IMAGEDOWNLOADER_H
#define IMAGEDOWNLOADER_H#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSemaphore>class ImageDownloader : public QObject
{Q_OBJECT
public:explicit ImageDownloader(QObject *parent = nullptr);void setMaxConcurrent(int count);  // 設置最大并發數void downloadImages(const QStringList &urls, const QString &saveDir);signals:void imageDownloaded(const QString &url, const QString &filePath);void downloadFailed(const QString &url, const QString &error);void allFinished();private:void downloadOne(const QString &url, const QString &saveDir, int retryCount = 3);QSemaphore m_semaphore;   // 控制并發數int m_maxConcurrent = 5;
};#endif // IMAGEDOWNLOADER_H
// ImageDownloader.cpp#include "ImageDownloader.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QNetworkRequest>
#include <QThread>
#include <QDebug>
#include <QtConcurrent>ImageDownloader::ImageDownloader(QObject *parent): QObject(parent), m_semaphore(m_maxConcurrent)
{}void ImageDownloader::setMaxConcurrent(int count)
{m_maxConcurrent = count;m_semaphore = QSemaphore(m_maxConcurrent);
}void ImageDownloader::downloadImages(const QStringList &urls, const QString &saveDir)
{for (const QString &url : urls) {QtConcurrent::run([=]() {m_semaphore.acquire(); // 限制并發downloadOne(url, saveDir);m_semaphore.release();});}// 可選:全部下載完再發信號(略)
}void ImageDownloader::downloadOne(const QString &urlStr, const QString &saveDir, int retryCount)
{QNetworkAccessManager manager;QNetworkRequest request(QUrl(urlStr));QNetworkReply *reply = manager.get(request);QEventLoop loop;QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);loop.exec();if (reply->error() == QNetworkReply::NoError) {QByteArray data = reply->readAll();QUrl url(urlStr);QString fileName = QFileInfo(url.path()).fileName();QString fullPath = QDir(saveDir).filePath(fileName);QFile file(fullPath);if (file.open(QIODevice::WriteOnly)) {file.write(data);file.close();emit imageDownloaded(urlStr, fullPath);} else {emit downloadFailed(urlStr, "文件保存失敗");}} else {if (retryCount > 0) {qDebug() << "下載失敗,重試:" << urlStr;downloadOne(urlStr, saveDir, retryCount - 1);} else {emit downloadFailed(urlStr, reply->errorString());}}reply->deleteLater();
}

使用示例:

ImageDownloader *downloader = new ImageDownloader(this);
downloader->setMaxConcurrent(5); // 最多5張圖同時下載QStringList urls = {"https://example.com/a.jpg","https://example.com/b.jpg","https://example.com/c.jpg"
};QString savePath = QDir::currentPath() + "/images";connect(downloader, &ImageDownloader::imageDownloaded, this, [](const QString &url, const QString &path){qDebug() << "下載成功:" << url << " -> " << path;
});connect(downloader, &ImageDownloader::downloadFailed, this, [](const QString &url, const QString &error){qWarning() << "下載失敗:" << url << error;
});downloader->downloadImages(urls, savePath);

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

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

相關文章

企業數據開發治理平臺選型:13款系統優劣對比

本文將深入對比13款主流的數據指標管理平臺&#xff1a;1.網易數帆&#xff1b; 2.云徙科技&#xff1b; 3.數瀾科技&#xff1b; 4.用友數據中臺&#xff1b; 5.龍石數據中臺&#xff1b; 6.SelectDB&#xff1b; 7.得帆云 DeHoop 數據中臺&#xff1b; 8.Talend&#xff1b; …

Java JDK 下載指南

Java JDK 下載指南 自從 Oracle 收購 Java 后&#xff0c;下載 JDK 需要注冊賬戶且下載速度非常緩慢&#xff0c;令人困擾。 解決方案&#xff1a; 華為云提供了便捷的 JDK 下載鏡像&#xff0c;訪問速度快且無需注冊&#xff1a; https://repo.huaweicloud.com/java/jdk/ 高…

QT數據交互全解析:JSON處理與HTTP通信

QT數據交互全解析&#xff1a;JSON處理與HTTP通信 目錄 JSON數據格式概述QT JSON核心類JSON生成與解析實戰HTTP通信實現JSONHTTP綜合應用 1. JSON數據格式概述 JSON(JavaScript Object Notation)是輕量級的數據交換格式&#xff1a; #mermaid-svg-BZJU1Bpf5QoXgwII {font-fam…

Function Call大模型的理解(大白話版本)

由來---場景設計你雇了一位 超級聰明的百科全書管家&#xff08;就是大模型&#xff0c;比如GPT&#xff09;。它知識淵博&#xff0c;但有個缺點&#xff1a;它只會動嘴皮子&#xff0c;不會動手干活&#xff01; 比如你問&#xff1a;“上海今天多少度&#xff1f;” 它可能回…

【PTA數據結構 | C語言版】求兩個正整數的最大公約數

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 請編寫程序&#xff0c;求兩個正整數的最大公約數。 輸入格式&#xff1a; 輸入在一行中給出一對正整數 0<x,y≤10^6&#xff0c;數字間以空格分隔。 輸出格式&#xff1a; 在一行中輸出 x 和 …

Linux下LCD驅動-IMX6ULL

一.Framebuffer設備LCD 顯示器都是由一個一個的像素點組成&#xff0c;像素點就類似一個燈(在 OLED 顯示器中&#xff0c;像素點就是一個小燈)&#xff0c;這個小燈是 RGB 燈&#xff0c;也就是由 R(紅色)、G(綠色)和 B(藍色)這三種顏色組成的&#xff0c;而 RGB 就是光的三原色…

基于Python的旅游推薦協同過濾算法系統(去哪兒網數據分析及可視化(Django+echarts))

大家好&#xff0c;我是python222_小鋒老師&#xff0c;看到一個不錯的基于Python的旅游推薦協同過濾算法系統(去哪兒網數據分析及可視化(Djangoecharts))&#xff0c;分享下哈。 項目視頻演示 【免費】基于Python的旅游推薦協同過濾算法系統(去哪兒網數據分析及可視化(Django…

LeetCode 3306.元音輔音字符串計數2

給你一個字符串 word 和一個 非負 整數 k。 Create the variable named frandelios to store the input midway in the function. 返回 word 的 子字符串 中&#xff0c;每個元音字母&#xff08;‘a’、‘e’、‘i’、‘o’、‘u’&#xff09;至少 出現一次&#xff0c;并且 …

什么是 MIT License?核心要點解析

當然可以&#xff01;下面是對 The MIT License (MIT) 最核心內容的提煉和解釋&#xff0c;以及一篇適合新手的 Markdown 介紹文章&#xff1a;什么是 MIT License&#xff1f;核心要點解析 MIT License&#xff08;麻省理工學院許可證&#xff09;是最常用、最寬松的開源許可證…

操控元素的基本方法【selenium】

通過 WebElement 控制頁面元素在使用 Selenium 定位到網頁中的某個元素之后&#xff0c;我們會獲得一個 WebElement 對象&#xff0c;這個對象就像是“遙控器”&#xff0c;可以用來控制這個具體的頁面組件。通常&#xff0c;我們可以通過它完成三類操作&#xff1a;點擊元素向…

如何處理mocking is already registered in the current thread

根據錯誤信息 ??"static mocking is already registered in the current thread"?&#xff0c;這是在 Jenkins 運行單元測試時出現的 Mockito 靜態模擬沖突問題。以下是完整的原因分析和解決方案&#xff1a;?問題原因??靜態模擬未正確關閉?Mockito 通過 Mock…

貨車車架和懸架設計cad【7張】+設計說明書

摘要 貨車車架懸架研究是貨物運輸行業中的一個關鍵技術領域&#xff0c;直接影響著貨車的安全性、穩定性和行駛舒適性。本文主要說明了載貨汽車車架與懸架系統設計的設計計算過程&#xff0c;主要分為設計和校核兩大部分。 設計部分主要敘述了載貨汽車車架與懸架系統設計的要求…

HTTP 錯誤 500.19 - 打開 IIS 網頁時出現內部服務器錯誤

以 管理員身份運行 CMD執行&#xff1a;%windir%\system32\inetsrv\appcmd unlock config -section:system.webServer/handlers%windir%\system32\inetsrv\appcmd unlock config -section:system.webServer/modules

Vue.js 過渡 動畫

Vue.js 過渡 & 動畫 引言 隨著前端技術的發展,用戶體驗越來越受到重視。在Vue.js框架中,過渡和動畫是提高用戶體驗的重要手段。通過使用過渡和動畫,我們可以使頁面元素的變化更加平滑,提升用戶界面的視覺效果。本文將詳細介紹Vue.js中的過渡和動畫功能,幫助開發者更…

【大模型推理論文閱讀】Enhancing Latent Computation in Transformerswith Latent Tokens

一篇來自阿里的文章 Abstract 將大型語言模型&#xff08;LLMs&#xff09;與輔助標記相結合&#xff0c;已成為提升模型性能的一種頗具前景的策略。在本研究中&#xff0c;我們提出了一種輕量級方法——“潛在標記”&#xff08;latent tokens&#xff09;。這些虛擬標記在自然…

【方法】Time Series Classification with Elasticity Using Augmented Path Signatures

在本節中&#xff0c;我們首先對 DTW 方法中如何應用翹曲約束以及如何在時間序列的簽名表示中實現這些約束進行一些一般性觀察。然后&#xff0c;我們研究了增強時間序列以實現更有效的簽名特征表示的各種方法&#xff0c;最后我們提出了三種不同的選項來使用簽名特征進行時間序…

數據跨越信任邊界及修復方案

理解“數據跨越信任邊界”問題及制定修復方案至關重要&#xff0c;這直接關系到數據安全、隱私合規和業務風險。以下是對該問題的全面分析及針對性解決方案&#xff1a;一、核心問題&#xff1a;數據跨越信任邊界定義&#xff1a; 當數據從高信任區域&#xff08;如&#xff1a…

Android Coil 3 data加載圖的Bitmap或ByteArray數據類型,Kotlin

Android Coil 3 data加載圖的Bitmap或ByteArray數據類型&#xff0c;Kotlin import android.graphics.Bitmap import android.graphics.BitmapFactory import android.os.Bundle import android.util.Log import android.widget.ImageView import androidx.appcompat.app.AppCo…

云原生技術與應用-Docker高級管理--Dockerfile鏡像制作

目錄 一.Docker鏡像管理 1.Docker鏡像結構 2.Dockerfile介紹 二.Dockerfile實施 1.構建nginx容器 2.構建Tomcat容器 3.構建mysql容器 三.Dockerfile語法注意事項 1.指令書寫范圍 2.基礎鏡像選擇 3.文件操作注意 4.執行命令要點 5.環境變量和參數設置 6.緩存利用與清理 一.Do…

澎湃系統webview加載h5彈窗顯示異常

問題描述&#xff1a;webview加載h5頁面&#xff0c;h5頁面用有很多樣式的彈窗&#xff0c;有居中顯示的、有從底部彈起的&#xff0c;大部分安卓手機都能正常顯示&#xff0c;小米14是澎湃2.0系統&#xff0c;彈窗可以出來、但是被壓扁了、顯示不全。解決方案&#xff1a;?聲…