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

Qt/C++中的异步编程

Qt/C++中的异步编程

  • 1 介绍
  • 2 含义
    • 2.1 QtConcurrent
    • 2.2 std::future
    • 2.3 Qml中的Promise
  • 3 使用场景
  • 4 代码示例
  • 5 注意事项
    • 5.1异常处理
    • 5.2 线程安全
    • 5.3 性能优化
    • 5.4 线程间通信
    • 5.5 避免死锁

1 介绍

异步编程是现代应用程序开发中不可或缺的一部分。它允许程序在执行耗时任务时保持响应性,特别是在GUI应用程序中。在Qt/C++中,有多种方式来实现异步编程。本文将重点介绍如何使用Qt中的QtConcurrent库,Qml中ES6标准的Promise还有C++标准库std::future进行异步编程,并讲解他们之间的区别。


2 含义

2.1 QtConcurrent

QtConcurrent 命名空间提供了高级 API,使编写多线程程序成为可能,而无需使用诸如互斥、读写锁、等待条件或 semaphores 等低级线程原语。使用 QtConcurrent 编写的程序会根据可用处理器内核的数量自动调整所使用的线程数。这意味着现在编写的应用程序将来在多核系统上部署时仍可继续扩展。

  • Concurrent Map and Map-Reduce
    QtConcurrent 包含用于并行列表处理的函数式编程 API,包括用于共享内存(非分布式)系统的 MapReduce 和 FilterReduce 实现,以及用于管理 GUI 应用程序中异步计算的类:
    • QtConcurrent::map() 对容器中的每个项目应用一个函数,对项目进行就地修改。
    • QtConcurrent::mapped() 类似 map(),不同之处在于它返回一个带有修改的新容器。
    • QtConcurrent::mappedReduced() 类似于 mapped(),只不过修改后的结果被缩小或折叠成一个结果。
  • Concurrent Filter and Filter-Reduce
  • QtConcurrent::filter() 根据过滤函数的结果从容器中移除所有项目。
  • QtConcurrent::filtered() 类似filter(),但它返回一个包含过滤结果的新容器。
  • QtConcurrent::filteredReduced() 类似 filtered(),只是过滤后的结果被缩小或折叠成一个结果。
  • Concurrent Run (常用)
    • QtConcurrent::run() 在另一个线程中运行一个函数。
  • QFuture (常用) 表示异步计算的结果。它类似于标准库中的std::future,但集成了Qt的信号和槽机制,使用起来更加方便。
    • QFutureWatcher(常用) 允许使用信号和插槽监控 QFuture
    • QFutureIterator 允许遍历通过 QFuture 获得的结果。
    • QFutureSynchronizer 是一个方便的类,可自动同步多个 QFutures

2.2 std::future

  • std::future 对象用来访问异步操作的结果。具体细节可以参考我之前的文章《C++库std::future》。
  • std::promise对象用来设置异步操作的结果,并将其传递给关联的std::future对象。简而言之,std::promisestd::future配合使用,std::promise用于设置结果,std::future用于获取结果。

2.3 Qml中的Promise

Qml中使用的是JavaScript,Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。参考<<Promise含义>>


3 使用场景

需求设计
文件读取一个线程负责读取文件内容,完成后通过std::promise/QtConcurrent/Promise通知主线程文件内容已准备好。
压缩解压一个线程负责压缩或者解压文件,完成后通过std::promise/QtConcurrent/Promise通知主线程操作结果。
网络请求在进行网络请求时,可以使用std::promise/QtConcurrent/Promise在请求完成时通知结果,无论成功还是失败。
数据库查询异步执行数据库查询,查询完成后通过std::promise/QtConcurrent/Promise传递查询结果给主线程。
图像处理在另一个线程中处理图像(如缩放、滤镜应用),处理完成后通过promise告知处理结果。
复杂计算将复杂的计算任务分配给工作线程,计算结束后通过std::promise/QtConcurrent/Promise通知计算结果。
定时任务设置一个定时器,在特定时间点通过std::promise/QtConcurrent/Promise触发某个事件或通知。
视频转码视频转码是一个耗时任务,可以在转码完成时使用std::promise/QtConcurrent/Promise通知转换状态和输出路径。
并行算法在并行算法中,每个线程完成一部分计算后,可以使用std::promise/QtConcurrent/Promise汇总结果到主线程。
事件驱动系统在事件驱动的架构中,std::promise/QtConcurrent/Promise可用于异步事件的响应,例如事件处理完成的通知
资源加载游戏或应用中的资源加载(如纹理、音频)可以在后台线程进行,加载完毕后通过std::promise/QtConcurrent/Promise通知加载成功
缓存更新异步更新缓存内容,更新完成后通知其他等待该资源的线程
消息队列处理在处理消息队列时,每个消息的处理结果可以通过std::promise/QtConcurrent/Promise传递给等待的线程
异步日志记录日志写入操作可以异步执行,日志写入完成时通过std::promise/QtConcurrent/Promise通知日志系统
数据分析在进行大数据分析时,可以使用std::promise/QtConcurrent/Promise在分析任务完成后通知结果,以便进一步处理或展示
硬件交互与硬件设备的交互(如传感器读取、设备控制)可以是异步的,通过std::promise/QtConcurrent/Promise通知操作状态或读取结果。

4 代码示例

我们以一个压缩文件的场景为例,展示如何在Qt/C++中使用异步编程。
使用QtConcurrent进行文件压缩:

#include <QtConcurrent>
#include <QDebug>

相关文章:

Qt/C++中的异步编程

Qt/C++中的异步编程 1 介绍2 含义2.1 QtConcurrent2.2 std::future2.3 Qml中的Promise3 使用场景4 代码示例5 注意事项5.1异常处理5.2 线程安全5.3 性能优化5.4 线程间通信5.5 避免死锁1 介绍 异步编程是现代应用程序开发中不可或缺的一部分。它允许程序在执行耗时任务时保持响…...

解决javadoc一直找不到路径的问题

解决javadoc一直找不到路径的问题 出现以上问题就是我们在下载jdk的时候一些运行程序安装在C:\Program Files\Common Files\Oracle\Java\javapath下&#xff1a; 一开始是没有javadoc.exe文件的&#xff0c;我们只需要从jdk的bin目录下找到复制到这个里面&#xff0c;就可以使用…...

存储器的性能指标以及层次化存储器

存储器的性能指标 存储器有三个性能指标&#xff1a;速度、容量和位价&#xff08;每位价格&#xff09; 1.存储速度 &#xff08;1&#xff09;存取时间 想衡量存储速度&#xff0c;最直观的指标就是完成一次存储器读写操作所需要的时间&#xff0c;这叫做存取时间&#x…...

【C++】C++入门的杂碎知识点

思维导图大纲&#xff1a; namespac命名空间 什么是namespace命名空间namespace命名空间有什么用 什么是命名空间 namespace命名空间是一种域&#xff0c;它可以将内部的成员隔绝起来。举个例子&#xff0c;我们都知道有全局变量和局部变量&#xff0c;全局变量存在于全局域…...

springboot 整合redis问题,缓存击穿,穿透,雪崩,分布式锁

boot整合redis 压力测试出现失败 解决方案 排除lettuce 使用jedis <!-- 引入redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclus…...

免费个人站 独立站 wordpress 自建网站

制作免费网站 | 免费网站构建器 | WordPress.com https://bioinformatics7.wordpress.com WordPress.com...

散列函数的基本概念

散列函数 算法不能设计太过复杂 太复杂的散列函数&#xff0c;势必会消耗很多计算时间 散列函数生成的值要尽可能随机并且均匀分布 这样才能避免或者最小化散列冲突而且即便出现来冲突&#xff0c;散列到每个槽里的数据也会比较平均&#xff0c;不会出现某个槽内数据特别多…...

【C++拷贝构造函数深浅拷贝】

拷贝构造函数 注意&#xff1a;访问权限是public 拷贝构造函数&#xff1a;类名&#xff08;const 类名& 对象名&#xff09;{} 可以有多个参数 。 没有常引用就是普通构造函数 如果不写&#xff0c;编译器自己会给一个&#xff08;作用仅仅是赋值&#xff0c;默认拷…...

快速编译安装tensorrt_yolo

快速编译安装 安装 tensorrt_yolo 通过 PyPI 安装 tensorrt_yolo 模块&#xff0c;您只需执行以下命令即可&#xff1a; pip install -U tensorrt_yolo 如果您希望获取最新的开发版本或者为项目做出贡献&#xff0c;可以按照以下步骤从 GitHub 克隆代码库并安装&#xff1a; …...

外盘黄金期货需要注意什么?

为大家整理了关于黄金做单的五大原则&#xff0c;相信对于新手投资者来说肯定会产生一定的帮助。  1、看多空&#xff1a;主要有两种方法&#xff0c;基本面判断和技术面判断&#xff0c;基本面判断&#xff0c;主要是借助基本信息面&#xff0c;如政策。供需&#xff0c;产量…...

Allegro光绘Gerber文件、IPC网表、坐标文件、装配PDF文件导出打包

Allegro光绘Gerber文件、IPC网表、坐标文件、装配PDF文件导出打包 一、Gerber文件层叠与参数设置二、装配图文件设置导出三、光绘参数设置四、Gerber孔符图、钻孔表及钻孔文件输出五、输出Gerber文件六、输出IPC网表七、导出坐标文件八、文件打包 一、Gerber文件层叠与参数设置…...

mysql的索引可以分为哪些类型

MySQL的索引是用于提高查询性能的重要数据结构。不同类型的索引在不同的使用场景中具有不同的优势和适用性。 1. 主键索引&#xff08;Primary Key Index&#xff09; 特点&#xff1a;唯一且不允许 NULL 值。用途&#xff1a;唯一标识表中的每一行。自动创建&#xff1a;定义…...

Content type ‘application/x-www-form-urlencoded;charset=UTF-8‘ not supported

Content type application/x-www-form-urlencoded;charsetUTF-8 not supported 问题背景新增页面代码改造 问题背景 这里有一个需求&#xff0c;前端页面需要往后端传参&#xff0c;参数包括主表数据字段以及子表数据字段&#xff0c;由于主表与子表为一对多关系&#xff0c;在…...

【JavaEE进阶】——利用框架完成功能全面的图书管理系统

目录 &#x1f6a9;项目所需要的技术栈 &#x1f6a9;项目准备工作 &#x1f388;环境准备 &#x1f388;数据库准备 &#x1f6a9;前后端交互分析 &#x1f388;登录 &#x1f4dd;前后端交互 &#x1f4dd;实现服务器代码 &#x1f4dd;测试前后端代码是否正确 &am…...

WDF驱动开发-内存缓冲区

驱动程序通常使用内存缓冲区向/从框架和其他驱动程序传递数据&#xff0c;或在本地存储信息。 WDF常见的内存缓冲区包括框架内存对象(WDFMEMORY)、 lookaside、 MDL 和 本地缓冲区。 使用框架内存对象 框架使用 内存对象 来描述驱动程序从中接收并传递给框架的内存缓冲区。 每…...

c语言连接两个字符串

在C语言中&#xff0c;连接两个字符串可以使用 strcat 函数。这个函数将一个字符串复制到另一个字符串的末尾。使用 strcat 函数之前&#xff0c;需要确保目标字符串有足够的空间来容纳源字符串&#xff0c;否则可能会导致缓冲区溢出。 下面是一个使用 strcat 函数连接两个字符…...

基于springboot的大学计算机基础网络教学系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于springboot的大学计算机基础网络教学…...

UOS常用命令

shutdown 关机 reboot 重启 reboot -f 强制重启 history 查看使用的历史命令 history -c 清空命令行常见目录结构 /bin 存储常用用户指令 /boot 存放用于系统引导时使用的各种文件 /dev 存放设备文件 /etc 存放系统&#xff0c;服务的配置…...

vue3 如何给表单添加表单效验+正则表达式

校验要求 我们的表单中有密码、电话号码 &#xff0c;两项。 我们设置用密码为3到20位的非空字符 电话号码就用目前用的电话号码正则表达式&#xff0c;要求手机号码以 1 开头&#xff0c;第二位为 3 到 9 之间的数字&#xff0c;后面跟着任意 9 个数字&#xff0c;总共是 11…...

JavaScript算法实现dfs查找省市区路径

需求 存在如下数组&#xff0c;实现一个算法通过输入区名&#xff0c;返回省->市->区格式的路径&#xff0c;例如输入西湖区&#xff0c;返回浙江省->杭州市->西湖区。 // 定义省市区的嵌套数组 const data [{name: "浙江省",children: [{name: "…...

map文件分析

以下是一个具体的map文件示例&#xff0c;并附上详细的描述&#xff0c;帮助你更好地理解如何读取和分析map文件&#xff1a; 示例map文件 Memory ConfigurationName Origin Length Attributes FLASH 0x08000000 0x0…...

MySQL-创建表~数据类型

070-创建表 create table t_user(no int,name varchar(20),gender char(1) default 男);071-插入数据 语法格式&#xff1a; insert into 表名(字段名1, 字段名2, 字段名3,......) values (值1,值2,值3,......);insert into t_user(no, name, gender) values(1, Cupid, 男);字…...

【鸿蒙 HarmonyOS】Swiper组件

一、背景 项目中通常会遇到图片轮播&#xff0c;内容轮播的场景&#xff1b;如&#xff1a;在一些应用首页显示推荐的内容时&#xff0c;需要用到轮播显示的能力。 二、源码地址 ✍Gitee开源项目地址&#x1f449;&#xff1a;https://gitee.com/cheinlu/harmony-os-next-swi…...

玩具机器人脚本适合场景

玩具机器人脚本作为一个模拟的玩具机器人脚本&#xff0c;适合以下场合&#xff1a; 1.教育和学习&#xff1a;对于初学者和编程爱好者来说&#xff0c;这个脚本是一个很好的学习工具&#xff0c;可以帮助他们理解如何编写和执行简单的控制逻辑。 2.在计算机科学、机器人技术或…...

人工智能模型组合学习的理论和实验实践

组合学习&#xff0c;即掌握将基本概念结合起来构建更复杂概念的能力&#xff0c;对人类认知至关重要&#xff0c;特别是在人类语言理解和视觉感知方面。这一概念与在未观察到的情况下推广的能力紧密相关。尽管它在智能中扮演着核心角色&#xff0c;但缺乏系统化的理论及实验研…...

MySQL备份与恢复:确保数据的安全与可靠性

引言: 数据的安全性和可靠性的重要性 在现代企业和组织中,数据已经成为了最重要的资产之一。数据的安全性和可靠性对于企业的运营至关重要。首先,数据的安全性保证了敏感信息不会落入错误的手中,防止了潜在的经济损失和法律风险。其次,数据的可靠性则确保了企业能够准确…...

Noisee AI – AI音乐影片MV在线生成工具,专门为Suno的好搭子来了~

导读 现在很多各大平台&#xff0c;抖音、快手、微视&#xff0c;还不能直接发布音频文件&#xff0c;如果有一个好听的音乐想做成MV&#xff0c;怎么办呢&#xff1f; 这时候就是Noisee AI的主场&#xff0c;上传一段音乐加上简单的描述就可以在3-5分钟内生成一个可以发布到…...

实战计算机网络02——物理层

实战计算机网络02——物理层 1、物理层实现的功能2、数据与信号2.1 数据通信模型2.2 通信领域常用术语2.3 模拟信号和数字信号 3、信道和调制3.1 信道3.2 单工通信、半双工通信、全双工通信3.3 调制3.4 奈式准则3.5 香农定律 4、传输媒体4.1 导向传输媒体4.2 非导向传输媒体 5、…...

Doris:冷热分层

目录 一、冷热分层介绍 二、存储策略&#xff08;Storage policy&#xff09; 2.1 创建存储资源 2.2 创建存储策略 2.3 使用存储策略 三、使用限制 一、冷热分层介绍 冷热分层支持所有 Doris 功能&#xff0c;只是把部分数据放到对象存储上&#xff0c;以节省成本&am…...

28.启动与暂停程序

上一个内容&#xff1a;27.设计注入功能界面 以它 27.设计注入功能界面 的代码为基础进行修改 点击添加游戏按钮之后就把游戏启动了 CWndINJ.cpp文件中修改&#xff1a; void CWndINJ::OnBnClickedButton1() {// TODO: 在此添加控件通知处理程序代码/*ExeLst.InsertItem(0, L…...

wordpress旅行地图主题/成人职业培训机构

第九届北京高中数学知识应用竞赛初赛 第二题原题&#xff1a;一只老鼠为了躲避猫的追捕&#xff0c;跳入了半径为&#xff32;的圆形湖中&#xff0e;猫不会游泳&#xff0c;只能沿湖岸追击&#xff0c;并且总是试图使自己离老鼠最近(即猫总是试图使自己在老鼠离岸最近的点上)…...

西双版纳 网站建设/线上推广平台

linux RTC 驱动模型分析RTC(real time clock)实时时钟&#xff0c;主要作用是给Linux系统提供时间。RTC因为是电池供电的&#xff0c;所以掉电后时间不丢失。Linux内核把RTC用作“离线”的时间与日期维护器。当Linux内核启动时&#xff0c;它从RTC中读取时间与日期&#xff0c;…...

广州网站建设 致茂/2023年的新闻十条

如何将正在运行的 Oracle 数据库迁移到另一个系统使用 Oracle VM Server for SPARC 2.1作者&#xff1a;Orgad Kimchi 和 Roman Ivanov&#xff0c;2012 年 2 月如何配置 Oracle 服务器及其关联的存储阵列&#xff0c;以便可以在不中断的情况下将正在运行的 Oracle 数据库从一个…...

规范门户网站建设/石家庄关键词排名首页

随着我国社会经济的快速发展&#xff0c;“十二五”期间政府继续大力推动“平安城市”、“智慧城市”建设&#xff0c;另外安防监控设备企业自身的创新拓展加之与IT企业、电信企业、家电企业的交融发展&#xff0c;极大地扩充了安防的内涵和应用领域。我国安防行业又将进入一个…...

免费项目管理软件app/网站搜索引擎优化方法

文章目录1 像素与颜色空间2 图像在内存之中的存储方式3 通过 Mat.ptr() 方法遍历像素4 LUT : 查找表映射5 操作内存1 像素与颜色空间 存储像素值需要指定颜色空间和数据类型&#xff0c;其中颜色空间是指一个给定的颜色&#xff0c;如何组合颜色元素&#xff0c;及各元素如何编…...

做个网站上百度怎么做/相亲网站排名前十名

代码 在Delphi 开发中&#xff0c;常常应用到窗体消息传递&#xff0c;以达成某种操作要求&#xff0c;以下列举一个应用的例子&#xff0c;供大家参考。 自定义过程/函数方法&#xff1a;//发送字符串到指字句柄的窗口中 (接收窗体需用发送时的消息常量WM_COPYDATA)procedureS…...