Qt Concurrent 并發 Map 和 Map-Reduce

并發 Map 和 Map-Reduce

  • QtConcurrent::map()會對容器中的每個項目應用一個函數,對項目進行就地修改。
  • QtConcurrent::mapped() 類似于 map(),但它返回的是一個包含修改內容的新容器。
  • QtConcurrent::mappedReduced() 類似于 mapped(),只不過修改后的結果被縮小或折疊成一個結果。

上述每個函數都有一個阻塞變體,它返回最終結果而不是QFuture?。使用它們的方法與異步變體相同。

QList<QImage> images = ...;// Each call blocks until the entire operation is finished.
QList<QImage> future = QtConcurrent::blockingMapped(images, scaled);QtConcurrent::blockingMap(images, scale);QImage collage = QtConcurrent::blockingMappedReduced(images, scaled, addToCollage);

請注意,上述結果類型不是QFuture?對象,而是真正的結果類型(本例中為QList<QImage> 和 QImage)。

并發 Map

QtConcurrent::mapped() 接收一個輸入序列(=容器)和一個映射函數。然后,序列中的每個項目都會調用該映射函數,并返回一個包含映射函數返回值的新序列。

映射函數的形式必須是

U function(const T &t);

T 和 U 可以是任何類型(甚至可以是相同類型),但 T 必須與序列(序列=容器)中存儲的類型相匹配。函數返回修改或映射后的內容

本例展示了如何對序列中的所有項目應用縮放函數:

QImage scaled(const QImage &image)
{return image.scaled(100, 100);
}QList<QImage> images = ...;
QFuture<QImage> thumbnails = QtConcurrent::mapped(images, scaled);

映射結果可通過QFuture?獲取。有關如何在應用程序中使用QFuture?的詳細信息,請參閱QFuture?和QFutureWatcher?文檔。

如果您想就地修改序列,請使用 QtConcurrent::map()。map 函數的形式必須是

U function(T &t);

請注意,map 函數的返回值和返回類型不會被使用

使用 QtConcurrent::map() 類似于使用 QtConcurrent::mapped():

void scale(QImage &image)
{image = image.scaled(100, 100);
}QList<QImage> images = ...;
QFuture<void> future = QtConcurrent::map(images, scale);

由于序列是就地修改的,QtConcurrent::map() 不會通過QFuture?返回任何結果。不過,您仍然可以使用QFuture?和QFutureWatcher?來監控映射的狀態。

并發 Map-Reduce

QtConcurrent::mappedReduced() 類似于 QtConcurrent::mapped(),但不是返回包含新結果的序列,而是使用 reduce 函數將結果合并為一個值。

reduce 函數的形式必須是

V function(T &result, const U &intermediate)

T 是最終結果的類型,U 是映射函數的返回類型。注意,不使用 reduce 函數的返回值和返回類型。

像這樣調用 QtConcurrent::mappedReduced():

QImage scaled(const QImage &image)
{return image.scaled(100, 100);
}void addToCollage(QImage &collage, const QImage &thumbnail)
{QPainter p(&collage);static QPoint offset = QPoint(0, 0);p.drawImage(offset, thumbnail);offset += ...;
}QList<QImage> images = ...;
QFuture<QImage> collage = QtConcurrent::mappedReduced(images, scaled, addToCollage);

map 函數返回的每個結果都將調用一次 reduce 函數,并將中間?結果合并到結果變量中。QtConcurrent::mappedReduced() 保證每次只有一個線程調用 reduce,因此無需使用互斥來鎖定結果變量。QtConcurrent::ReduceOptions?枚舉提供了一種控制還原順序的方法。如果使用QtConcurrent::UnorderedReduce?(默認值),則順序未定義,而QtConcurrent::OrderedReduce?可確保按照原始序列的順序進行還原。

其他應用程序接口功能

使用迭代器代替序列

上述每個函數都有一個使用迭代器范圍而非序列的變體。使用方法與序列變體相同:

QList<QImage> images = ...;QFuture<QImage> thumbnails = QtConcurrent::mapped(images.constBegin(), images.constEnd(), scaled);// Map in-place only works on non-const iterators.
QFuture<void> future = QtConcurrent::map(images.begin(), images.end(), scale);QFuture<QImage> collage = QtConcurrent::mappedReduced(images.constBegin(), images.constEnd(), scaled, addToCollage);

阻塞變體

上述每個函數都有一個阻塞變體,它返回最終結果而不是QFuture?。使用方法與異步變體相同。

QList<QImage> images = ...;// Each call blocks until the entire operation is finished.
QList<QImage> future = QtConcurrent::blockingMapped(images, scaled);QtConcurrent::blockingMap(images, scale);QImage collage = QtConcurrent::blockingMappedReduced(images, scaled, addToCollage);

請注意,上述結果類型不是QFuture?對象,而是真正的結果類型(本例中為QList<QImage> 和 QImage)。

使用成員函數

QtConcurrent::map()、QtConcurrent::mapped()和 QtConcurrent::mappedReduced() 接受指向成員函數的指針。成員函數類的類型必須與存儲在序列中的類型相匹配:

// Squeeze all strings in a QStringList.
QStringList strings = ...;
QFuture<void> squeezedStrings = QtConcurrent::map(strings, &QString::squeeze);// Swap the rgb values of all pixels on a list of images.
QList<QImage> images = ...;
QFuture<QImage> bgrImages = QtConcurrent::mapped(images,static_cast<QImage (QImage::*)() const &>(&QImage::rgbSwapped));// Create a set of the lengths of all strings in a list.
QStringList strings = ...;
QFuture<QSet<int>> wordLengths = QtConcurrent::mappedReduced(strings, &QString::length,qOverload<const int&>(&QSet<int>::insert));

注意qOverload?的使用。需要使用它來解決有多個重載的方法的歧義問題。

還請注意,在使用 QtConcurrent::mappedReduced() 時,您可以自由混合使用普通函數和成員函數:

// Can mix normal functions and member functions with QtConcurrent::mappedReduced().// Compute the average length of a list of strings.
extern void computeAverage(int &average, int length);
QStringList strings = ...;
QFuture<int> averageWordLength = QtConcurrent::mappedReduced(strings, &QString::length, computeAverage);// Create a set of the color distribution of all images in a list.
extern int colorDistribution(const QImage &string);
QList<QImage> images = ...;
QFuture<QSet<int>> totalColorDistribution = QtConcurrent::mappedReduced(images, colorDistribution,qOverload<const int&>(&QSet<int>::insert));

使用函數對象

QtConcurrent::map()、QtConcurrent::mapped()和QtConcurrent::mappedReduced()接受map函數的函數對象。這些函數對象可用于為函數調用添加狀態:

struct Scaled
{Scaled(int size): m_size(size) { }typedef QImage result_type;QImage operator()(const QImage &image){return image.scaled(m_size, m_size);}int m_size;
};QList<QImage> images = ...;
QFuture<QImage> thumbnails = QtConcurrent::mapped(images, Scaled(100));

還原函數也支持函數對象:

struct ImageTransform
{void operator()(QImage &result, const QImage &value);
};QFuture<QImage> thumbNails =QtConcurrent::mappedReduced(images, Scaled(100), ImageTransform(),QtConcurrent::SequentialReduce);

使用 Lambda 表達式

QtConcurrent::map()、QtConcurrent::mapped()和 QtConcurrent::mappedReduced() 接受 map 和 reduce 函數的 lambda 表達式:

QList<int> vector { 1, 2, 3, 4 };
QtConcurrent::blockingMap(vector, [](int &x) { x *= 2; });int size = 100;
QList<QImage> images = ...;QList<QImage> thumbnails = QtConcurrent::mapped(images,[&size](const QImage &image) {return image.scaled(size, size);}).results();

當使用 QtConcurrent::mappedReduced() 或 QtConcurrent::blockingMappedReduced() 時,您可以自由混合使用普通函數、成員函數和 lambda 表達式

QList<QImage> collage = QtConcurrent::mappedReduced(images,[&size](const QImage &image) {return image.scaled(size, size);},addToCollage).results();

您還可以將 lambda 傳遞給 reduce 對象:

QList<QImage> collage = QtConcurrent::mappedReduced(images,[&size](const QImage &image) {return image.scaled(size, size);},[](QImage &result, const QImage &value) {// do some transformation}).results();

封裝包含多個參數的函數

如果要使用一個包含多個參數的 map 函數,可以使用 lambda 函數或std::bind()?將其轉換為一個包含一個參數的函數。

例如,我們將使用 QImage::scaledToWidth():

QImage QImage::scaledToWidth(int width, Qt::TransformationMode) const;

scaledToWidth 需要三個參數(包括 "this "指針),并且不能直接與 QtConcurrent::mapped() 一起使用,因為 QtConcurrent::mapped() 期望使用一個參數的函數。要在 QtConcurrent::mapped() 中使用 QImage::scaledToWidth(),我們必須提供寬度值和轉換模式

QList<QImage> images = ...;
std::function<QImage(const QImage &)> scale = [](const QImage &img) {return img.scaledToWidth(100, Qt::SmoothTransformation);
};
QFuture<QImage> thumbnails = QtConcurrent::mapped(images, scale);

Concurrent Map and Map-Reduce | Qt Concurrent 6.8.2

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

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

相關文章

RT-Thread-線程管理

一、線程管理 RT_Thread線程管理主要是實現線程管理和調度&#xff0c;線程分為用戶線程和系統線程。RT_Thread的線程調度器是搶占式的&#xff0c;尋找就緒狀態最高優先級線程。 線程管理的API函數 創建線程函數 rt_thread_t rt_thread_create( const char *name, //線程名稱 …

【CC2530 教程 十二】CC2530 Z-Stack 硬件抽象層

目錄 一、硬件抽象層簡介&#xff1a; &#xff08;1&#xff09;HAL 硬件抽象層是什么&#xff1f; &#xff08;2&#xff09;通俗易懂的解釋&#xff1a; &#xff08;3&#xff09;具體例子&#xff1a; 二、硬件抽象層HAL&#xff1a; &#xff08;1&#xff09;HAL…

Linux如何判斷磁盤是否已分區?

在 Linux 系統中&#xff0c;判斷磁盤是否已分區可通過以下方法實現&#xff1a; 方法 1&#xff1a;使用 fdisk -l 命令 此命令會列出所有磁盤及其分區的詳細信息&#xff1a; sudo fdisk -l輸出解讀&#xff1a; 若磁盤&#xff08;如 /dev/sdb&#xff09;下有類似 /dev/…

《熔化焊接與熱切割作業》考試注意事項

考試前的準備 攜帶必要的證件和材料&#xff1a;考生需攜帶身份證、準考證等有效證件&#xff0c;以及考試所需的焊接工具、材料等。確保證件齊全&#xff0c;避免因證件問題影響考試。 提前檢查焊接設備和工具&#xff1a;在考試前&#xff0c;考生應仔細檢查焊接設備和工具是…

Matlab Hessian矩陣計算(LoG算子)

文章目錄 一、簡介二、實現代碼三、實現效果參考資料一、簡介 圖像的Hessian矩陣用于描述圖像灰度值的二階導數,可以用來分析圖像的局部曲率和變化。例如,在圖像邊緣檢測、特征點檢測等任務中,Hessian矩陣能幫助我們識別圖像的結構。 Hessian矩陣定義 對于二維圖像,Hessian…

selenium之處理彈框(alert、confirm、prompt)

彈框 WebDriver提供了一個API, 用于處理JavaScript提供的三種類型的原生彈窗消息. 這些彈窗由瀏覽器提供限定的樣式.&#xff1b;分別為以下三種 alerts警告框confirm確認框prompt提示框 話不多說&#xff0c;開始實踐下就知道怎么一回事了 alerts 警告框&#xff0c;顯示…

Visual Studio 2019 Qt QML 項目環境搭建常見問題處理方法

在 Visual Studio 2019 運行 Qt/QML 項目比直接使用QtCreator環境麻煩&#xff0c;主要是有qmake 的一些配置項不能在 Visual Studio中設置。下面整理一些常見問題的處理方法&#xff0c;供參考&#xff1a; 搭建VS Qt 環境&#xff0c;在Visual Studios 2019下面安裝 Qt Vis…

【Linux】POSIX信號量與基于環形隊列的生產消費者模型

目錄 一、POSIX信號量&#xff1a; 接口&#xff1a; 二、基于環形隊列的生產消費者模型 環形隊列&#xff1a; 單生產單消費實現代碼&#xff1a; RingQueue.hpp&#xff1a; main.cc&#xff1a; 多生產多消費實現代碼&#xff1a; RingQueue.hpp&#xff1a; main.…

RAG優化:python從零實現GraphRag 一場文檔與知識的“戀愛”之旅

嘿,親愛的算法工程師們,準備好迎接一場文檔與知識的“戀愛”之旅了嗎?今天我們要介紹的 Graph RAG,就像是一位“紅娘”,幫助文檔和知識在圖的世界里找到彼此,擦出智慧的火花! 文章目錄 為什么需要 Graph RAG?Graph RAG 的“戀愛秘籍”準備好了嗎?讓我們開始吧!環境設…

深入 SVG:矢量圖形、濾鏡與動態交互開發指南

1.SVG 詳細介紹 SVG&#xff08;Scalable Vector Graphics&#xff09; 是一種基于 XML 的矢量圖形格式&#xff0c;用于描述二維圖形。 1. 命名空間 (Namespace) ★ 了解 命名空間 URI&#xff1a;http://www.w3.org/2000/svg 用途&#xff1a;在 XML 或 XHTML 中區分不同標…

HTTPS 加密過程詳解

HTTPS 的核心組成是 HTTP 協議與 SSL/TLS 加密層的結合&#xff0c;通過加密傳輸、身份驗證和完整性校驗機制&#xff0c;確保數據安全。其加密過程通過以下方式保障數據的機密性、完整性和身份驗證&#xff1a; 一、HTTPS 的核心組成 1. HTTP 協議 作為基礎通信協議&#xf…

嵌入式硬件工程師從小白到入門-速通版(一)

嵌入式硬件工程師從小白到入門&#xff1a;知識點速通與實戰指南 一、基礎硬件知識體系 電子電路基礎 基本概念&#xff1a;電流、電壓、電阻、電容、電感等&#xff1b;電路分析&#xff1a;歐姆定律、基爾霍夫定律、戴維南定理&#xff1b;元器件特性&#xff1a;二極管、三極…

SpringBoot通過Map實現天然的策略模式

&#x1f60a; 作者&#xff1a; 一恍過去 &#x1f496; 主頁&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社區&#xff1a; Java技術棧交流 &#x1f389; 主題&#xff1a; SpringBoot通過Map實現天然的策略模式 ?? 創作時間&#xff1a; 202…

WordPress WooCommerce 本地文件包含漏洞(CVE-2025-1661)

免責聲明 僅供網絡安全研究與教育目的使用。任何人不得將本文提供的信息用于非法目的或未經授權的系統測試。作者不對任何由于使用本文信息而導致的直接或間接損害承擔責任。如涉及侵權,請及時與我們聯系,我們將盡快處理并刪除相關內容。 一:產品介紹 HUSKY – WooCommer…

matlab近似計算聯合密度分布

在 Matlab 中&#xff0c;當A和B是兩個序列數據時&#xff0c;可以通過以下步驟來近似求出A大于B的概率分布&#xff1a;數據準備&#xff1a;確保序列A和B具有相同的長度。如果長度不同&#xff0c;需要進行相應的處理&#xff08;例如截取或插值&#xff09;。計算A大于B的邏…

可視化動態表單動態表單界的天花板--Formily(阿里開源)

文章目錄 1、Formily表單介紹2、安裝依賴2.1、安裝內核庫2.2、 安裝 UI 橋接庫2.3、Formily 支持多種 UI 組件生態&#xff1a; 3、表單設計器3.1、核心理念3.2、安裝3.3、示例源碼 4、場景案例-登錄注冊4.1、Markup Schema 案例4.2、JSON Schema 案例4.3、純 JSX 案例 1、Form…

NAT 實驗:多私網環境下 NAPT、Easy IP 配置及 FTP 服務公網映射

NAT基本概念 定義&#xff1a;網絡地址轉換&#xff08;Network Address Translation&#xff0c;NAT&#xff09;是一種將私有&#xff08;保留&#xff09;地址轉化為合法公網 IP 地址的轉換技術&#xff0c;它被廣泛應用于各種類型 Internet 接入方式和各種類型的網絡中。作…

C語言-橋接模式詳解與實踐

文章目錄 C語言橋接模式詳解與實踐1. 什么是橋接模式&#xff1f;2. 為什么需要橋接模式&#xff1f;3. 實際應用場景4. 代碼實現4.1 UML 關系圖4.2 頭文件 (display_bridge.h)4.3 實現文件 (display_bridge.c)4.4 使用示例 (main.c) 5. 代碼分析5.1 關鍵設計點5.2 實現特點 6.…

el-table 合并單元格

vue2使用el-table合并單元格&#xff0c;包括合并行、合并列 <el-table:header-cell-style"handerMethod":span-method"arraySpanMethod"cell-click"handleCellClick":data"tableData"style"width: 100%"><el-tabl…

網絡安全之vlan實驗

在對vlan進行一定的學習之后我們來練習一個小實驗來加深理解記憶 首先是對實驗進行一個搭建 第一部分&#xff1a;給交換機配置vlan 首先是sw1 [Huawei]vlan batch 2 to 5 [Huawei]int g0/0/1 [Huawei-GigabitEthernet0/0/1]port hybrid tagged vlan 2 [Huawei-GigabitEthe…