当前位置: 首页 > news >正文

Qt Concurrent框架详解(QFuture、QFutureWatcher)

1.概述

Qt Concurrent是Qt提供的一个并发编程框架,用于简化多线程和并行计算的开发。它提供了一组易于使用的函数和类,可以方便地在多线程环境下处理并发任务。

有以下特点:

简单易用:Qt Concurrent提供了一组高级函数和类,使多线程和并行计算变得简单易用。开发者无需显式地创建和管理线程,而是通过调用Qt Concurrent提供的函数实现并发任务。

自动任务分割:Qt Concurrent能够根据可用的线程数自动将大的问题拆分成更小的任务,并分配给不同的线程并行执行。这样能够最大程度地利用系统资源,提高并发执行效率。

异步计算:Qt Concurrent提供了异步执行任务的机制,可以在后台执行任务,同时不会阻塞主线程,从而提高用户界面的响应性。 主要的类和函数:

  • QFuture:表示一个异步任务的未来结果。可以通过调用QFuture的result()方法来获取结果。还可以使用QFutureWatcher类来监视并处理异步任务的结果。
  • QFutureIterator:用于遍历QFuture所代表的异步任务的结果集合。
  • QThread:Qt Concurrent内部会自动管理线程,不需要手动创建和管理线程。但如果需要更细粒度的控制线程的操作,可以使用QThread类。
  • QtConcurrent::run():用于在后台线程执行函数。它会自动创建一个新的线程,并在该线程中执行指定的函数。
  • QtConcurrent::map():用于并行计算,将一个函数应用于一个容器中的每个元素,并返回结果集。它会根据可用的线程数自动进行任务分割和分配。
  • QtConcurrent::filter():根据指定的谓词函数,在容器中筛选符合条件的元素。也会进行任务分割和分配。
  • QtConcurrent::blockingMapped():与map类似,但是会阻塞当前线程直到所有任务完成。

2.常用方法

在 pro 文件添加“Qt += concurrent”并且在我们的 h 文件添加“#include <QtConcurrent>”,就可以使用这些函数了。基本上所有的 concurrent 函数分为三种类型:

  • run 相关:执行函数用;
  • map 相关:处理容器中的每一项;
  • filter 相关:筛选容器中的每一项。

run方法:创建一个新的线程,并在该线程中执行指定的函数。

  • QFuture<T> run(Function function, ...)
  • QFuture<T> run(QThreadPool *pool, Function function, ...)

map方法:在单独的线程里对容器中的每一项进行操作,并返回结果集。

  • QtConcurrent::map():直接操作容器中的每一项。
  • QtConcurrent::mapped():操作容器中的每一项,将处理结果返回一个新的容器,原容器不变。
  • QtConcurrent::mappedReduced():在 mapped() 的基础上将处理结果进一步传递给一个函数继续处理。

filter方法:filter 相关函数和 map 相关函数类似,也是对容器中的元素进行处理,但 filter 更多侧重筛选元素。

  • QtConcurrent::filter()
  • QtConcurrent::filtered()
  • QtConcurrent::filteredReduced()

3.示例

示例1:将普通函数运行在两个不同的线程中,使用QFuture的result()方法来获取返回结果。

#include <QApplication>
#include <QFuture>
#include <QtConcurrent>QString func1()
{qDebug()<<"我是func1函数";
}
QString func2(QString name)
{qDebug()<<"我是func2函数";return name;
}int main(int argc, char *argv[])
{QCoreApplication  a(argc, argv);//用QFuture获取该函数的运行结果QFuture<QString> fut1 = QtConcurrent::run(func1);//参数2:向func函数传递的参数QFuture<QString> fut2 = QtConcurrent::run(func2, QString("func2"));QString result2 = fut2.result();fut1.waitForFinished();fut2.waitForFinished();qDebug()<<"result2 = "<<result2;return a.exec();
}

运行结果:

示例2: 使用QtConcurrent::map(),QtConcurrent::mapped() ,QtConcurrent::mappedReduced()

map:直接操作容器中的每一项,不返回。

mapped:操作容器中的每一项,将处理结果返回一个新容器,原容器不变。

mappedReduced:mapped() 的基础上将处理结果进一步传递给下一个函数继续处理。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QFuture>
#include <QtConcurrent>void processString1(QString& str) {str = str.toUpper();   //转大写
}QString processString2(const QString& str) {// 模拟一些复杂的处理逻辑QThread::msleep(1000);  // 延迟1秒return str.toUpper();   //转大写
}void processString3(QString &result, const QString &intermedia)
{result += " ";result += intermedia;
}MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);QStringList strings1 = {"hello", "world", "qt", "concurrent"};QFuture<void> fut1 = QtConcurrent::map(strings1, processString1);fut1.waitForFinished();qDebug()<<"==========result1=========";for(const QString& result : strings1) {qDebug() << result;}qDebug()<<"==========result1=========";qDebug()<<"==========result2=========";QStringList strings2 = {"hello", "world", "qt", "concurrent"};QFuture<QString> future = QtConcurrent::mapped(strings2, processString2);future.waitForFinished();QList<QString> results = future.results();for(const QString& result : results) {qDebug() << result;}qDebug()<<"==========result2=========";qDebug()<<"==========result3=========";QStringList strings3 = {"hello", "world", "qt", "concurrent"};QFuture<QString> future2 = QtConcurrent::mappedReduced(strings3, processString2,processString3);future2.waitForFinished();QList<QString> results2 = future2.results();for(const QString& results : results2) {qDebug() << results;}qDebug()<<"==========result3=========";
}MainWindow::~MainWindow()
{delete ui;
}

运行结果:

 示例3:使用QFutureWatcher来监视并处理异步任务的结果。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QFuture>
#include <QtConcurrent>
#include <QFutureWatcher>QFutureWatcher<QStringList> watcher;QStringList processString(const QStringList& str) {// 模拟一些复杂的处理逻辑QThread::msleep(1000);  // 延迟1秒QStringList ret;for(int i=0;i<str.size();i++){ret.append(str.at(i).toUpper());}return ret;
}MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);QStringList strings = {"hello", "world", "qt", "concurrent"};QFuture<QStringList> future = QtConcurrent::run(processString, strings);watcher.setFuture(future);QObject::connect(&watcher, &QFutureWatcher<void>::finished, this, [&]() {qDebug() << "All tasks finished!";for(const QString& result2 : watcher.result()) {qDebug() << result2;}});QObject::connect(&watcher, &QFutureWatcher<void>::progressValueChanged, [](int value) {qDebug() << "Progress: " << value << "%";});}MainWindow::~MainWindow()
{delete ui;
}

运行结果:

相关文章:

Qt Concurrent框架详解(QFuture、QFutureWatcher)

1.概述 Qt Concurrent是Qt提供的一个并发编程框架&#xff0c;用于简化多线程和并行计算的开发。它提供了一组易于使用的函数和类&#xff0c;可以方便地在多线程环境下处理并发任务。 有以下特点&#xff1a; 简单易用&#xff1a;Qt Concurrent提供了一组高级函数和类&…...

zip函数用法:解压与打包

解释 在 Python 中&#xff0c;zip 函数可以用于两种情况&#xff1a;打包&#xff08;压缩&#xff09;和解压&#xff08;解包&#xff09;。 1.打包&#xff08;压缩&#xff09;&#xff1a; 当传递多个可迭代对象作为参数给 zip 函数时&#xff0c;它会将这些可迭代对象…...

这一份免费API接口集合,开发者必备

台风信息查询&#xff1a;提供西北太平洋及南海地区过去两年及当前年份所有编号台风的信息查询&#xff0c;包括台风实时位置、过去路径、预报路径及登陆信息等要素。未来7天生活指数&#xff1a;支持国内3400个城市以及国际4万个城市的天气指数数据&#xff0c;包括晨练、洗车…...

【IDEA】设置sql提示

第一步&#xff1a;注入SQL语言 1.首先选择任意一条sql语句&#xff0c;右击&#xff0c;选择 ‘显示上下文操作’ 2.选择 ‘注入语言或引用’ 3. 往下翻&#xff0c;找到MySQL 第二步&#xff1a;配置MySQL数据库连接 1.首先点击侧边的数据库&#xff0c;再点击上面的加号 2…...

Swagger + DOCWAY 一步导出为优雅完整的Markdown、Pdf接口文档

只要开发&#xff0c;只要写接口应该没人不知道Swagger&#xff0c;但DOCWAY可能知道的人不多&#xff0c;但知道用过后就离不开了&#xff0c;不管是作为多方联调的接口文档&#xff0c;还是交接给客户的文档&#xff0c;都是可以的&#xff0c;具体如何使用&#xff0c;详细步…...

HTML链接、头部

HTML链接&#xff1a; HTML使用超级链接与网络上的另一个文档相连。HTML中的链接是一种用于在不同网页之间的导航的元素。链接通常用于将一个网页与另一个网页或资源&#xff08;文档、图像、音频文件等&#xff09;相关联。链接允许用户在浏览网页时单击文本或图像来跳转到其他…...

IDEA优雅自动生成类注释和快捷键生成方法注释

生成类注释 Preferences->Editor->File and Code Templates-> Includes ->File Header 注释模板&#xff1a; /*** Classname ${NAME}* Description ${description}* Date ${DATE} ${TIME}* Created by ZouLiPing*/生成方法和字段注释 查看IDEA自动配置java快捷…...

数据库面试题整理

目录 MySQL事务隔离级别有哪几种&#xff1f;MySQL的常用的存储引擎有哪些&#xff1f;特点是什么&#xff0c;分别适合什么场景下使用MySQL有数据缓存吗&#xff1f;原理是怎么样的&#xff1f;InnoDB的缓冲池默认是开启的吗&#xff1f;基本原理是什么&#xff1f;会有脏数据…...

【无标题】输入日期是当年的第n天

从键盘输入正确日期&#xff0c;程序输出是当年的第n天。 (本笔记适合熟悉循环和列表的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那么…...

金蝶云星空自定义校验器和使用

文章目录 金蝶云星空自定义校验器和使用 金蝶云星空自定义校验器和使用 1、创建类&#xff0c;并继承抽象接口 using Kingdee.BOS.Core; using Kingdee.BOS.Core.Validation; using System;namespace mm.K3.SCM.App.Service.PlugIn.SC.Validator {public class AfterOrderChe…...

MyBatis实验(四)——关联查询

前言 多表关联查询是软件开发中最常见的应用场景&#xff0c;多表查询需要将数据实体之间的一对多、多对多、一对一的关系的转换为复杂的数据对象。mybaits提供的association和collection元素&#xff0c;通过映射文件构造复杂实体对象&#xff0c;在构造实体过程中&#xff0…...

Redis与Mysql的数据一致性(双写一致性)

双写一致性&#xff1a;当修改了数据库的数据也要同时的更新缓存的数据&#xff0c;使缓存和数据库的数据要保持一致。 一般是在写数据的时候添加延迟双删的策略 先删缓存 再修改数据 延迟一段时间后再次删除缓存 这种方式其实不是很靠谱 一致性要求高 共享锁&#xff1a;读…...

sql-50练习题16-20

sql-50练习题16-20 前言数据库表结构介绍学生表课程表成绩表教师表 1-6 检索"01"课程分数小于60&#xff0c;按分数降序排列的学生信息1-7 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩1-8 查询各科成绩最高分、最低分和平均分&#xff1a;以如下形式…...

算法通关村第四关|青铜|自己实现栈

1.自己实现栈——基于数组 top 有的地方指向栈顶元素&#xff0c;有的地方指向栈顶再往上的一个空单位&#xff0c;根据题目要求设计。 *这里将 top 设置为栈顶再往上的一个空单位。 import java.util.Arrays; class Mystack<T> {private Object[] stack;// 指向栈顶…...

Calcite 自定义优化器规则

1&#xff09;总结 1.创建 CSVProjectRule 继承 RelRule<CSVProjectRule.Config> a&#xff09;在 CSVProjectRule.Config 接口中实现匹配规则 Config DEFAULT EMPTY.withOperandSupplier(b0 ->b0.operand(LogicalProject.class).anyInputs()).as(Config.class);b…...

【flink】flink获取-D参数方式

参考官网 一、idea 本地运行 使用Flink官方的ParameterTool或者其他工具都可以。 二、集群运行flink run/run-application &#xff08;1&#xff09;ParameterTool 获取参数 以-D开头的参数&#xff1a; ParameterTool parameter ParameterTool.fromSystemProperties()…...

NLP之多循环神经网络情感分析

文章目录 代码展示代码意图代码解读知识点介绍 代码展示 import pandas as pd import tensorflow as tf# 构建RNN神经网络 tf.random.set_seed(1) df pd.read_csv("../data/Clothing Reviews.csv") print(df.info())df[Review Text] df[Review Text].astype(str) …...

【AutoML】AutoKeras 的安装和环境配置(VSCode)

本地环境中已经有太多的工作配置了&#xff08;Python、Java、Maven、Docker 等等&#xff09;&#xff0c;为了不影响其他环境运行&#xff0c;我选择直接在 VSCode 中创建工作空间并配置好 AutoKeras&#xff08;反正最后也是要在 VSCode 中进行开发的&#xff09;。 打开 V…...

树结构及其算法-用数组来实现二叉树

目录 树结构及其算法-用数组来实现二叉树 C代码 树结构及其算法-用数组来实现二叉树 使用有序的一维数组来表示二叉树&#xff0c;首先可将此二叉树假想成一棵满二叉树&#xff0c;而且第层具有个节点&#xff0c;按序存放在一维数组中。首先来看看使用一维数组建立二叉树的…...

知识图谱与大模型结合方法概述

《Unifying Large Language Models and Knowledge Graphs: A Roadmap》总结了大语言模型和知识图谱融合的三种路线&#xff1a;1&#xff09;KG增强的LLM&#xff0c;可在LLMs的预训练和推理阶段引入KGs&#xff1b;2&#xff09;LLM增强KG&#xff0c;LLM可用于KG构建、KG emb…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

LangChain【6】之输出解析器:结构化LLM响应的关键工具

文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器&#xff1f;1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...

基于 HTTP 的单向流式通信协议SSE详解

SSE&#xff08;Server-Sent Events&#xff09;详解 &#x1f9e0; 什么是 SSE&#xff1f; SSE&#xff08;Server-Sent Events&#xff09; 是 HTML5 标准中定义的一种通信机制&#xff0c;它允许服务器主动将事件推送给客户端&#xff08;浏览器&#xff09;。与传统的 H…...

Electron简介(附电子书学习资料)

一、什么是Electron&#xff1f; Electron 是一个由 GitHub 开发的 开源框架&#xff0c;允许开发者使用 Web技术&#xff08;HTML、CSS、JavaScript&#xff09; 构建跨平台的桌面应用程序&#xff08;Windows、macOS、Linux&#xff09;。它将 Chromium浏览器内核 和 Node.j…...

(12)-Fiddler抓包-Fiddler设置IOS手机抓包

1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求&#xff0c;也可以截获各种智能手机发出的HTTP/ HTTPS 请求。 Fiddler 能捕获Android 和 Windows Phone 等设备发出的 HTTP/HTTPS 请求。同理也可以截获iOS设备发出的请求&#xff0c;比如 iPhone、iPad 和 MacBook 等苹…...

视觉slam--框架

视觉里程计的框架 传感器 VO--front end VO的缺点 后端--back end 后端对什么数据进行优化 利用什么数据进行优化的 后端是怎么进行优化的 回环检测 建图 建图是指构建地图的过程。 构建的地图是点云地图还是什么信息的地图&#xff1f; 建图并没有一个固定的形式和算法…...