QtConcurrent 线程使用说明

2023-10-28

关于Qt Concurrent,我们首先来看看Qt Assitant是怎么描述的。

The QtConcurrent namespace provides high-level APIs that make it possible to write multi-threaded programs without using low-level threading primitives such as mutexes, read-write locks, wait conditions, or semaphores. Programs written with QtConcurrent automatically adjust the number of threads used according to the number of processor cores available. This means that applications written today will continue to scale when deployed on multi-core systems in the future.

说简单点,就是我们使用QtConcurrent 实现多线程时,可以不用考虑对共享数据的保护问题。而且,它可以根据CPU的能力,自动优化线程数。

QtConcurrent 主要提供了3种实现多线程的方法,分别是:run,map,filter。下面分别进行详细说明使用方法。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(Qt实战项目,C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

目录

  • Concurrent run,在线程池内起一个线程来执行一个函数。
  • Concurrent map, 用于并行处理一批数据的场景。
  • Concurrent Filter,顾名思义,一般用于对一批数据的过滤操作。

Concurrent run,在线程池内起一个线程来执行一个函数。基本用法如下:

extern void aFunction();
QFuture<void> future = QtConcurrent::run(aFunction);
//std::thread 实现
std::thread thread = std::thread(aFunction);
thread.detach();

如上,标准库的thread 也能实现相同功能。不同的是,QtConcurrent 实现的线程,可以获取到线程函数的返回值。

extern QString functionReturningAString();
QFuture<QString> future = QtConcurrent::run(functionReturningAString);
...
QString result = future.result();

QtConcurrent::run() 也提供了线程函数传参的实现:

extern QString someFunction(const QByteArray &input);
QByteArray bytearray = ...;
QFuture<QString> future = QtConcurrent::run(someFunction, bytearray);
...
QString result = future.result();

另外,同std::thread, QtConcurrent::run() 也提供了成员函数实现线程的方案。

1)调用const 函数

QByteArray bytearray = "hello world";
QFuture<QList<QByteArray> > future = QtConcurrent::run(bytearray, &QByteArray::split, ',');

或,

QFuture<QList<QByteArray> > future = QtConcurrent::run(&bytearray, &QByteArray::split, ',');

2)调用非const 函数

QImage image = ...;
QFuture<void> future = QtConcurrent::run(&image, &QImage::invertPixels, QImage::InvertRgba);

Concurrent map, 用于并行处理一批数据的场景。主要包含map, mapped, mappedReduced 三种用法。

map 函数用于需要更改原数据的使用场景,使用方法如下:

void toUpper(QString &str)
{
    str = str.toUpper();
}
QStringList strWords;
strWords << "Apple" << "Banana" << "cow" << "dog" << "Egg";
auto future =  QtConcurrent::map(strWords, toUpper);
future.waitForFinished();
//strWords = {"APPLE", "BANANA", "COW", "DOG", "EGG"}

mapped 函数用于不改变原数据,返回处理结果的使用场景。使用方法如下:

QString toUpper(const QString &str)
{
    return str.toUpper();
}
QStringList strWords;
strWords << "Apple" << "Banana" << "cow" << "dog" << "Egg";
auto future =  QtConcurrent::mapped(strWords, toUpper);
future.waitForFinished();
qDebug() << future.results();
//输出:("APPLE", "BANANA", "COW", "DOG", "EGG")

mappedReduced 用于mapped处理后的结果还需要进行处理的使用场景。使用方法如下:

QString toUpper(const QString &str)
{
    return str.toUpper();
}
void reduceFun(QList<QString> &dictionary, const QString &string)
{
    dictionary.push_back(QString("result: ") + string);
}
 
QStringList strWords;
strWords << "Apple" << "Banana" << "cow" << "dog" << "Egg";
auto future =  QtConcurrent::mappedReduced(strWords, toUpper, reduceFun);
future.waitForFinished();
qDebug() << future.result();
//输出:("result: BANANA", "result: APPLE", "result: COW", "result: DOG", "result: EGG")

注意,上述代码输处结果的顺序与原数据的顺序已经不一样了。mappedReduced 函数的逻辑是,启动多个线程执行toUper 对链表中的每个元素进行处理,处理后的结果再逐一交给reduceFun函数处理。reduceFun 并不会等toUper的所有线程执行完毕后才开始执行,并且,同一时刻,只有一个reduceFun 线程在执行。如果需要使最后的输出结果顺序与输入相一致,就要用到mappedReduced 函数的第四个参数,赋值为QtConcurrent::OrderedReduce, 即可保证顺序一致。

同样的,Concurrent map也提供了成员函数作为线程函数的使用形式。线程函数必须是序列中元素的类型的成员函数。Qt 帮助文档中给出了如下示例:

// 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, &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, &QSet<int>::insert);

Concurrent map 还可以使用函数对象。Qt 帮助文档中给出了如下示例:

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));

Concurrent Filter,顾名思义,一般用于对一批数据的过滤操作。同样也包含filter, filtered, filteredReduce 三种用法。

filter 函数必须按如下形式定义,T类型与处理数据的元素类型一致,返回false时,过滤掉相应的元素。

bool function(const T &t);

与Concurrent map 类似,filter 函数会改变原始数据,filtered 函数将处理结果保存在filtered 函数的返回值中,filteredReduce 会将过滤后的数据再调用reduceFun 函数处理。这里就不再进行详细赘述,可以完全参考map函数的用法使用。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(Qt实战项目,C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QtConcurrent 线程使用说明 的相关文章

  • 【满分】【华为OD机试真题2023 JS】狼羊过河

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 狼羊过河 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 一农夫带着m只羊 n只狼过河 农夫有一条可载x只狼 羊的船 农夫在时或者羊的数量大于狼时 狼不会攻击羊

随机推荐

  • 剪映电脑版详细使用教程,让视频剪辑变得更简单了

    这几天关于剪映电脑版的消息非常多 相比于专业成熟的视频剪辑软件 但大家对这款剪映似乎特别感兴趣 小编也抽时间简单使用了一下 相比于adobe Premiere 和达芬奇来说 真的特别简单上手 结合了手机版的触摸与鼠标操作 新手也能简单上手了
  • 软件测试主要考点梳理以及真题讲解(附答案)

    需要题目答案及相关复习资料关注后留言私信即可 白驹过隙 转眼大学三年就过去了 软件测试与维护也成为大学中最后一门考试的科目 接下来为大家总结一下软件测试与维护考试的主要内容 题型 以及真题答案 一 题型 题型仅限于我们学校 SCUT 其他学
  • EDA12--DC脚本命令(一)

    这里写目录标题 一 流程简介 二 启动DC 三 读入与链接 3 1 analyze elaborate 3 1 1 analyze命令 3 1 2 elaborate命令 3 2 read命令 四 工作环境设置 4 1 设置工作条件 4 2
  • STM32——PWM(呼吸灯&舵机使用)

    目录 1 与pwm相关的函数介绍 1 1 输出比较函数配置 1 1 1 以下四个函数是配置图1中的四个比较单元 1 1 2 输出结构体赋默认值 1 2 单独修改参数的相关函数 1 2 1 单独设置极性相关函数 1 2 2 单独修改输出使能参
  • 数字图像处理领域的二十四个典型算法

    转自 http blog csdn net v JULY v article details 6210124 作者 July 二零一一年二月二十六日 参考 百度百科 维基百科 vc数字图像处理 数字图像处理领域的二十四个典型算法及vc实现
  • 计算机中丢失MSVCR120.dll,电脑找不到MSVCR120.dll怎么办

    在电脑打开浏览器后在顶部栏目搜索或许点击这里传送门 dll修复程序 site 按下回车键然后进入下载msvcp120 dll系统文件 1 然后再打开解压好的文件 打开后点击开始安装电脑丢失的msvcp120 dll文件 2 开始快速的进行相
  • 半监督目标检测(三)

    目录 ISMT 动机 1 Overview 2 Pseudo Labels Fusion 3 Interactive Self Training 4 Mean Teacher Unbiased Teacher 动机 1 Overview 2
  • H5使用hook实现网络连接情况判断

    最近使用hook写了一个小练习 作用就是判断网络的连接情况 并在连接情况变化的时候可以作出一系列的操作 话不多说 上代码 function useCheckOnline navigator onLine代表当前的网络连接情况 const o
  • 第六课:MAC去中心化钱包开发之备份私钥

    一 私钥 这节课继续将注册Token后的步骤 就是备份私钥 每个公链都会有私钥 但是不尽相同 MAC底层的私钥比较多 有4个 分别是 钱包钥匙 钱包钥匙是开启MAC钱包的必备信息之一 格式为mac三个字母开头的一长串字符 创建钱包账户后会提
  • 新人小白求助大佬

    本人在进行病例对照匹配 想要匹配比是1 2 匹配条件是年龄 3岁 孕周 3周 我之前用的R语言代码是MatchIt代码 代码如下 这个代码有两个问题 一个是匹配方法 method 中没有范围的选项 只能按照 nearest 或者 exact
  • Ubuntu18.04中修改Ubuntu的外观(菜单栏放到屏幕下方)

    因为用的synergy分屏使用 所以想要将Ubuntu18 04的左侧栏放到屏幕底部 因为鼠标在点击左侧另一个电脑侧边栏的时候会不小心点到 过程 安装gnome tweak tool感觉是最方便的 直接打开命令行 先安装配置工具 sudo
  • 第三回:布局格式定方圆

    文章目录 第三回 布局格式定方圆 一 子图 1 使用 plt subplots 绘制均匀状态下的子图 2 使用 GridSpec 绘制非均匀子图 二 子图上的方法 思考题 第三回 布局格式定方圆 import numpy as np imp
  • Vuejs实践--事件绑定

    Vue中的事件绑定一般通过v on指令来绑定事件 事件绑定 v on 事件绑定的表达式的值可以是js语句 也可以是在methods选项中定义好的方法名 有参数的时候当然需要传参 在vue事件中 如果要用到事件对象e 要将e作为形参传入函数
  • SpringBoot 之 MDC 实现全链路调用日志跟踪

    文章目录 日志拦截器 修改日志格式 trackId 丢失解决 日志拦截器 import com evcas charge pile platform common annotation LogNoTrace import com evcas
  • STM32 基础系列教程 18 – IWDG

    前言 学习stm32 独立看门狗 IWDG 接口使用 学会用STM32内部独立看门狗 IWDG 实现程序异常时自复位功能 STM32F10xxx内置两个看门狗 提供了更高的安全性 时间的精确性和使用的灵活性 两个看门狗设备 独立看门狗和窗口
  • 计算机网络——SOCKET、TCP、HTTP之间的区别与联系

    文章目录 一 Socket 1 什么是socket 2 为什么需要socket 3 建立socket连接 4 socket分类 二 HTTP 基于TCP 1 HTTP的概念 2 HTTP连接的特点 2 1 连接请求 一次连接 2 2 连接请
  • 专栏《乔新亮的CTO成长复盘》读书笔记(技术架构篇)

    架构决策能力不但非常关键 而且是技术管理者最重要的能力和职责之一 而且职级越高就越重要 很多所谓的 技术债 也就是由一次次的决策失误不断累加而成的 管理者要能充分利用自己的技术视野和业务认知提前做好预判和布局 也就是上医治未病 做 T 型人
  • 滑动谜题 -- BFS

    滑动谜题 输入 board 4 1 2 5 0 3 输出 5 解释 最少完成谜板的最少移动次数是 5 一种移动路径 尚未移动 4 1 2 5 0 3 移动 1 次 4 1 2 0 5 3 移动 2 次 0 1 2 4 5 3 移动 3 次
  • Python Selenium 基本使用(详细步骤)

    一 简介 Selenium 是一个 web 应用程序自动化测试工具 对各种浏览器都能很好地支持 包括 Chrome Firefox 这些主流浏览器 使用它可以模拟浏览器进行各种各样的操作 包括爬取一些网页内容 当看到浏览器自己运行并且在网页
  • QtConcurrent 线程使用说明

    关于Qt Concurrent 我们首先来看看Qt Assitant是怎么描述的 The QtConcurrent namespace provides high level APIs that make it possible to wr