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提供的一个并发编程框架,用于简化多线程和并行计算的开发。它提供了一组易于使用的函数和类,可以方便地在多线程环境下处理并发任务。 有以下特点: 简单易用:Qt Concurrent提供了一组高级函数和类&…...
zip函数用法:解压与打包
解释 在 Python 中,zip 函数可以用于两种情况:打包(压缩)和解压(解包)。 1.打包(压缩): 当传递多个可迭代对象作为参数给 zip 函数时,它会将这些可迭代对象…...
这一份免费API接口集合,开发者必备
台风信息查询:提供西北太平洋及南海地区过去两年及当前年份所有编号台风的信息查询,包括台风实时位置、过去路径、预报路径及登陆信息等要素。未来7天生活指数:支持国内3400个城市以及国际4万个城市的天气指数数据,包括晨练、洗车…...

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

Swagger + DOCWAY 一步导出为优雅完整的Markdown、Pdf接口文档
只要开发,只要写接口应该没人不知道Swagger,但DOCWAY可能知道的人不多,但知道用过后就离不开了,不管是作为多方联调的接口文档,还是交接给客户的文档,都是可以的,具体如何使用,详细步…...

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

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

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

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

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

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

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

sql-50练习题16-20
sql-50练习题16-20 前言数据库表结构介绍学生表课程表成绩表教师表 1-6 检索"01"课程分数小于60,按分数降序排列的学生信息1-7 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩1-8 查询各科成绩最高分、最低分和平均分:以如下形式…...
算法通关村第四关|青铜|自己实现栈
1.自己实现栈——基于数组 top 有的地方指向栈顶元素,有的地方指向栈顶再往上的一个空单位,根据题目要求设计。 *这里将 top 设置为栈顶再往上的一个空单位。 import java.util.Arrays; class Mystack<T> {private Object[] stack;// 指向栈顶…...
Calcite 自定义优化器规则
1)总结 1.创建 CSVProjectRule 继承 RelRule<CSVProjectRule.Config> a)在 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 (1)ParameterTool 获取参数 以-D开头的参数: 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)
本地环境中已经有太多的工作配置了(Python、Java、Maven、Docker 等等),为了不影响其他环境运行,我选择直接在 VSCode 中创建工作空间并配置好 AutoKeras(反正最后也是要在 VSCode 中进行开发的)。 打开 V…...

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

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

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...