Qt/C++中的异步编程

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/

相关推荐

  1. Qt/C++异步编程

    2024-06-15 14:36:05       10 阅读
  2. Flutter Stream:异步编程利器

    2024-06-15 14:36:05       40 阅读
  3. C#Task:异步编程瑞士军刀

    2024-06-15 14:36:05       17 阅读
  4. Swift协程与异步编程

    2024-06-15 14:36:05       19 阅读
  5. Promise-以往异步编程模式

    2024-06-15 14:36:05       17 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-15 14:36:05       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-15 14:36:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-15 14:36:05       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-15 14:36:05       20 阅读

热门阅读

  1. 鸿蒙 如何将base64的图片保存到相册

    2024-06-15 14:36:05       8 阅读
  2. blender

    blender

    2024-06-15 14:36:05      5 阅读
  3. 难or易?c++

    2024-06-15 14:36:05       7 阅读
  4. web前端黑马下载:探索学习资源的海洋

    2024-06-15 14:36:05       7 阅读
  5. Gobject tutorial 二

    2024-06-15 14:36:05       4 阅读
  6. 刷题理解JVM内部的数据存储

    2024-06-15 14:36:05       8 阅读
  7. C 语言实例 - 输出数组

    2024-06-15 14:36:05       7 阅读
  8. c语言中的gets()函数记录

    2024-06-15 14:36:05       10 阅读
  9. 八、BGP

    八、BGP

    2024-06-15 14:36:05      5 阅读
  10. TypeScript中的Symbol,确实唯一。。。

    2024-06-15 14:36:05       6 阅读
  11. 认识一些分布-关于极值点分布的一些知识

    2024-06-15 14:36:05       7 阅读