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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/27696.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序优化 --- arthas trace命令使用

最近在做优化,通过arthas的trace命令去观察方法内的耗时情况以便对程序进行修改. 1.启动arthas之后选择需要监测的程序 2.找到需要监测的接口,一般都是直接找service例子如下: trace 类地址.类名 方法名 (中间有空格)

代码随想录算法训练营第39天(py)| 动态规划 | 62.不同路径、 63. 不同路径 II

62.不同路径 力扣链接 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路…

DDPM公式推导(二)

2 Background 扩散模型【53】是一种以 p θ ( x 0 ) : ∫ p θ ( x 0 : T ) d x 1 : T p_\theta\left(\mathbf{x}_0\right):\int p_\theta\left(\mathbf{x}_{0: T}\right) d \mathbf{x}_{1: T} pθ​(x0​):∫pθ​(x0:T​)dx1:T​ 形式的潜在变量模型&#xff0c;其中 x 1…

Nginx实战:故障处理_后端服务正常,nginx偶发502(Bad Gateway)

一、故障场景 用户访问服务偶发报错【502 Bad Gateway】&#xff0c;但是服务后端正常运行。架构如下&#xff1a; #mermaid-svg-4dDszusKEuPgIPlt {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-4dDszusKEuPgIPlt…

Qt项目天气预报(1) - ui界面搭建

ui中部 效果演示 ui效果 显示效果 控件列表 配合右图查看 居中对齐-label 设置label居中对齐(别傻傻的空格对齐了) 间距配置 widget03 外围的widget对象: 包含label 和 widget0301&#xff0c;如下图 widget0301 内围的widget对象&#xff0c;如下图 样式表 widget03 …

自养号测评全揭秘:沃尔玛卖家如何实现销量稳步增长

在沃尔玛这片激烈的商业战场上&#xff0c;我作为一位销售者&#xff0c;深知在这个竞争激烈的市场中&#xff0c;测评对于提升产品排名、权重以及销量的关键作用。随着测评需求的不断增长&#xff0c;我们意识到&#xff0c;寻找可靠的测评服务不再是简单的选择&#xff0c;而…

数组模拟单链表和双链表

目录 单链表 初始化 头插 删除 插入 双链表 初始化 插入右和插入左 删除 单链表 单链表主要有三个接口&#xff1a;头插&#xff0c;删除&#xff0c;插入&#xff08;由于单链表的性质&#xff0c;插入接口是在结点后面插入&#xff09; 初始化 int e[N], ne[N]; …

【scikit-learn入门指南】:机器学习从零开始

1. 简介 scikit-learn是一款用于数据挖掘和数据分析的简单高效的工具&#xff0c;基于NumPy、SciPy和Matplotlib构建。它能够进行各种机器学习任务&#xff0c;如分类、回归和聚类。 2. 安装scikit-learn 在开始使用scikit-learn之前&#xff0c;需要确保已经安装了scikit-le…

pyinstall打包exe报错

1- 报错 Please install pywin32-ctypes. 前提&#xff1a;python安装路径中已经安装了pywin32-ctypes。 运行pyinstaller报错 PyInstaller cannot check for assembly dependencies. Please install pywin32-ctypes. 解决思路&#xff1a; python安装路径下Lib\site-packa…

算法:位运算题目练习

目录 常见的位运算的操作总结 ①基础位操作 ②给一个数n&#xff0c;确定它的二进制表示中的第x位是0还是1 ③将一个数n的二进制表示的第x位修改成1 ④将一个数n的二进制表示的第x位修改成0 ⑤位图的思想 ⑥提取一个数n二进制表示中最右侧的1 ⑦干掉一个数n二进制表示中…

JVM 根可达算法

Java中的垃圾 Java中"垃圾"通常指的是不再被程序使用和引用的对象&#xff0c;具体表现在没有被栈、JNI指针和永久代对象所引用的对象。Java作为一种面向对象的编程语言&#xff0c;它使用自动内存管理机制&#xff0c;其中垃圾收集器负责检测和回收不再被程序引用的…

响应式德米拉数字内容交易系统素材下载站模板

★模板说明★ 该数字交易系统设计非常完美&#xff0c;两种响应式模式&#xff0c;可打开边栏模式和盒子模式&#xff1b;八种网站颜色&#xff0c;四种风格颜色可供用户自行选择&#xff0c;还可在网站选背景图片&#xff1b;完美的分成系统、充值功能、个人中心等等都以html…

可重复读(Repeatable Read) 隔离级别-幻读

幻读通常发生在范围查询中&#xff0c;下面通过一个简单的例子来说明幻读现象&#xff1a; 假设有一个名为 employees 的表&#xff0c;其中包含员工的ID和部门ID&#xff1a; CREATE TABLE employees (id INT,department_id INT,name VARCHAR(255) );现在有两个并发事务 A 和…

警示:AGI竞赛之未来十年

后新冠时代&#xff0c;人类智商普遍下降&#xff0c;人工智能赶超人类智能指日可待。 最近几天&#xff0c;AI领域悄悄流行一份AGI白皮书&#xff0c;虽然有些危言耸听&#xff0c;甚至包含以中国为竞争对手的阴谋论。下面是主要思想&#xff1a; 在过去的一年里&#xff1a…

速盾:被攻击后开ddos防御还有效吗?

在网络世界中&#xff0c;DDOS&#xff08;分布式拒绝服务&#xff09;攻击是一种常见且具有极大破坏力的网络攻击手段。当网站或系统遭受此类攻击后&#xff0c;一个关键的问题便是此时开启 DDOS 防御是否仍然有效。作为一名专业程序员&#xff0c;以下是对这一问题的深入分析…

6.11 作业

以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴子等。现在&#xff0c;动物园里有一位讲解员&…

找我设计官网的不多了,看到漂亮大气的,还是忍不住分享出来。

现在有客户找我做官网设计&#xff0c;我说&#xff1a;要么搞个高大上个性化定制的&#xff0c;要么就选个模板得了&#xff0c;几千元的网站不上不下&#xff0c;不如不做。 分享一批高大上的网站给老铁们看看。

功能强大的API函数FindFirstFile使用介绍(附源码)

在处理文件的相关代码中,会频繁使用到Windows系统API函数FindFirstFile,这个函数功能很强大,很多功能都不开它。本文就根据我们在项目中使用该函数的情况,来大概地梳理一下使用FindFirstFile都可以实现哪些常用的功能。 1、FindFirstFile函数声明与WIN32_FIND_DATA结构体 我…

C++ 33 之 const 修饰静态成员

#include <iostream> #include <string.h> using namespace std;// 定义静态const数据成员时&#xff0c;最好在类内部初始化,避免在类外重复初始化&#xff0c;也为了代码的可读性和可维护性class Students03{ public:// 两种写法都可以const static int s_a 10;…

开源模型应用落地-LangChain高阶-LCEL-表达式语言(六)

一、前言 尽管现在的大语言模型已经非常强大,可以解决许多问题,但在处理复杂情况时,仍然需要进行多个步骤或整合不同的流程才能达到最终的目标。然而,现在可以利用langchain来使得模型的应用变得更加直接和简单。 LCEL是什么? LCEL是一种非常灵活和强大的语言,可以帮助您更…