QCoro: Qt C++ 20 协程库介绍

C++20 推出了协程的实现(coroutines)。虽然开发一个支持协程特性的类库还是要花很多功夫的,但是使用一个开发好的类库则是非常嗨。这也是C++ 委员会一贯的原则:

如果你是类库开发者,必须足够有耐心学习拗口的特性。但如果是类库使用者,则直接吃语法糖爽歪歪就行了

协程是一种线程内的快速执行序切换功能,比回调函数调用起来要简单。这篇文章介绍了协程的基本概念。

QCoro 是 Qt 的一个协程库,利用C++20的特性,可以显著简化以前用信号-槽回调才能完成的操作。代码可从github下载。

例子

QCoro库提供了一组工具来使用C++20与Qt的协同程序。下面的例子演示了下载一些网络数据的实现对比(传统信号槽和协程)。

以前使用Lambda槽回调时,为了生存周期,需要显式new Qt对象,并deleteLater。

传统信号槽:

void MyClass::fetchData() {auto *nam = new QNetworkAccessManager(this);auto *reply = nam->get(QUrl{QStringLiteral("https://.../api/fetch")});QObject::connect(reply, &QNetworkReply::finished,[reply, nam]() {const auto data = reply->readAll();doSomethingWithData(data);reply->deleteLater();nam->deleteLater();});
}

现在只要稍微注意一下上下文的生存周期,就可以直接用栈上的局部变量调用IO操作,并保持事件循环。

协程:

QCoro::Task<> MyClass::fetchData() {QNetworkReply nam;auto *reply = co_await nam.get(QUrl{QStringLiteral("https://.../api/fetch")});const auto data = reply->readAll();reply->deleteLater();doSomethingWithData(data);
}

这里的神奇之处在于co-await关键字,它将方法fetchData()变成了一个协程,并在网络请求运行时暂停了它的执行。当请求完成时,协程将从暂停的位置恢复并继续。注意!当co_await 暂停时,Qt事件循环照常运行!

官网的解释

下面的段落试图以简单的方式解释什么是协同程序以及co_await做什么。我不能保证这些都是事实上正确的。有关更详细(和正确)的信息,请参阅本文底部链接的文章。

简单地说,Coroutine类似于普通函数,只是它们可以在中间挂起(和恢复)。当协同程序被挂起时,执行返回到调用了协同程序的函数。如果该函数也是协同程序,并且正在等待(co_awaiting)当前协同程序完成,则它也将被挂起,执行将返回到调用该协同程序的函数,依此类推,直到到达作为实际函数(而不是协同程序)的函数。在常规Qt程序的情况下,这个“顶级”非协同程序函数将是Qt的事件循环——这意味着当从Qt事件循环调用协同程序时,当您的协同程序被挂起时,Qt事件环将继续运行,直到再次恢复协同程序。

在许多其他事情中,这允许您编写异步代码,就像它是同步的一样,而不会阻塞Qt事件循环,并使应用程序无响应。请参阅本文档中的不同示例。

现在让我们看看co_await关键字。这个关键字告诉编译器,这是协同程序希望挂起的点,直到等待的对象(awaitable)准备就绪。任何类型都可以是可等待的——要么是因为它直接实现C++协同程序机械所需的接口,要么是因为提供了一些外部工具(如该库)来将该类型包装为实现可等待接口的东西。

C++协同程序引入了两个额外的关键字-co_return和co_yield:

从应用程序程序员的角度来看,co_return的行为与return完全相同,只是您不能在协同程序中使用常规return。然而,在引擎盖下有一些主要的区别,这可能是为什么有一个用于从协同程序返回的特殊关键字的原因。

coyield允许协同程序在不实际返回的情况下生成结果。可以用于写入生成器。目前,这个库没有对co_yield的支持/使用,因此我在这里不再赘述。

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

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

相关文章

MySQL分区的优缺点

前言 数据库中的分区技术为处理大规模数据提供了一种有效的手段&#xff0c;通过将数据划分成更小的可管理单元&#xff0c;我们能够提高查询性能、简化数据维护并更灵活地管理存储空间。然而&#xff0c;在采用分区时&#xff0c;我们必须认真考虑分区键的选择和实施细节&…

vue封装滚动表格

1.组件的使用 <div style"height:93%; overflow: hidden;"> <autoScroll :data"shortageList" :speed"0.5" :waitTime"500" :singleHeight"100" v-if"shortageList.length>0"><el-row v-for…

ACM训练题:曲线

这题只需要注意一个点&#xff0c;就是所有二次函数的二次系数都是大于0的&#xff0c;这说明这是个下凸函数&#xff0c;而且最小值旁边都是单调的&#xff0c;对于求区间凸函数极值问题&#xff0c;套三分模板即可。 AC代码&#xff1a; #include<bits/stdc.h> usin…

2023年全球软件开发大会(QCon上海站2023):核心内容与学习收获(附大会核心PPT下载)

在信息化和全球化日益加速的今天&#xff0c;软件开发技术日新月异&#xff0c;对全球各行各业产生了深远影响。2023年全球软件开发大会&#xff08;QCon上海站2023&#xff09;无疑成为行业内外瞩目的焦点。本次大会汇集了全球顶级的软件开发专家、企业领袖、研究者&#xff0…

nextcloud 优化扩展

cd /config vi config.php #ONLYOFFICE allow_local_remote_servers > true, #应用商店加速 appstoreenabled > true, appstoreurl > https://www.orcy.net/ncapps/v2/, #nginx配置调优 add_header Strict-Transport-Security max-age15552000; add…

cesium-加载谷歌影像

cesium在开发的时候有可能会加载不同的影像&#xff0c;今天就先看一下加载谷歌的吧。 使用谷歌有个好处就是基本不会出现此区域无卫星图的情况 闲言话语不多说&#xff0c;看代码 <template><div id"cesiumContainer" style"height: 100vh;"&g…

在nodejs中使用mysql2

目录 安装 mysql2:导入 mysql2 模块:创建数据库连接:执行查询操作:关闭数据库连接: 在之前的项目中nodejs模板使用的mysql包&#xff0c;mysql数据库版本是5.7&#xff0c;最近更新了数据库版本为mysql8&#xff0c;发现之前的代码无法成功连接数据库&#xff0c;经过排查发现问…

力扣题目训练(7)

2024年1月31日力扣题目训练 2024年1月31日力扣题目训练387. 字符串中的第一个唯一字符389. 找不同401. 二进制手表109. 有序链表转换二叉搜索树114. 二叉树展开为链表52. N 皇后 II 2024年1月31日力扣题目训练 2024年1月31日第七天编程训练&#xff0c;今天主要是进行一些题训…

springboot jar包编写启动start.sh

对于Spring Boot应用&#xff0c;由于其内置了用于启动的主类&#xff08;默认为org.springframework.boot.loader.JarLauncher或你自定义的SpringBootApplication注解的类&#xff09;&#xff0c;因此start.sh脚本可以相对简化。以下是一个针对Spring Boot应用的start.sh脚本…

springcloud-gateway升级版本allowedOrigins要改allowedOriginPatterns

前言 报错: java.lang.IllegalArgumentException: When allowCredentials is true,allowedOrigins cannot contain the special value "*"since that cannot be set on the "Access-Control-Allow-Origin"response header. To allow credentials to a se…

C语言第十八弹---指针(二)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 指针 1、const修饰指针 1.1、const修饰变量 1.2、const修饰指针变量 2、指针运算 2.1、指针- 整数 2.2、指针-指针 2.3、指针的关系运算 3、野指针 3.1、…

HBase 数据导入导出

HBase 数据导入导出 1. 使用 Docker 部署 HBase2. HBase 命令查找3. 命令行操作 HBase3.1 HBase shell 命令3.2 查看命名空间3.3 查看命名空间下的表3.4 新建命名空间3.5 查看具体表结构3.6 创建表 4. HBase 数据导出、导入4.1 导出 HBase 中的某个表数据4.2 导入 HBase 中的某…

linux系统haproxy负载均衡工具的介绍以及使用

haproxy 概述haproxy的特点haproxy算法haproxy做四层负载均衡haproxy做七层负载均衡 概述 ha-proxy是一款高性能的负载均衡软件。其专注于负载均衡这一些事情&#xff0c;因此与nginx比起来&#xff0c;负载均衡做的更好haproxy---主要是做负载均衡的7层&#xff0c;也可以做4…

视觉惯性SLAM系列——ORB-SLAM3的整体介绍及各个线程的功能(五)

ORB-SLAM3的整体介绍及各个线程的功能&#xff08;五&#xff09; ORB-SLAM3是一个多线程的系统&#xff0c;它主要包含以下几个线程&#xff0c;每个线程负责不同的功能&#xff1a; 跟踪线程&#xff08;Tracking Thread&#xff09;&#xff1a; 作用&#xff1a;负责处理每…

openGauss DataPod资源池化获金融科技产业联盟2023年十佳课题

NEWS 近日&#xff0c;由中国人民银行指导的北京金融科技产业联盟公布2023年度十佳课题评选结果&#xff0c;由openGauss社区牵头的《资源池化数据库金融关键业务场景技术研究》荣获了“北京金融科技产业联盟2023年度十佳课题。” 2023年&#xff0c;openGauss发布5.0.0和5.1.…

【Node系列】node核心模块util

文章目录 一、util介绍二、util模块函数三、node介绍四、热门文章推荐 一、util介绍 Node.js的核心模块util为开发者提供了一些常用的实用工具函数。这些函数能够很方便地进行对象的继承、类型判断以及其他工具函数的实现。 util模块主要提供了以下几个功能&#xff1a; 继承…

vulhub中 Apache Airflow Celery 消息中间件命令执行漏洞复现(CVE-2020-11981)

Apache Airflow是一款开源的&#xff0c;分布式任务调度框架。在其1.10.10版本及以前&#xff0c;如果攻击者控制了Celery的消息中间件&#xff08;如Redis/RabbitMQ&#xff09;&#xff0c;将可以通过控制消息&#xff0c;在Worker进程中执行任意命令。 1.利用这个漏洞需要控…

Postgresql源码(120)事务XID分配与主备XID同步

参考 《Postgresql源码&#xff08;25&#xff09;子事务可见性判断和性能问题》 XID获取顶层入口 函数&#xff1a;AssignTransactionId static void AssignTransactionId(TransactionState s) {...优先给没有事务ID的父事务分配 确保父事务有 XID&#xff0c;以便子事务总是…

倒计时65天

复习2。 一.╥﹏╥...倒计时72天╥﹏╥...-CSDN博客 1.* #include<bits/stdc.h> using namespace std; #define int long long const int N3e35; const int inf0x3f3f3f3f; int a[N][N],b[N][N]; void solve() {int n;cin>>n;for(int i1;i<n;i){for(int j1;j…

Spring Boot 依赖管理:spring-boot-dependencies vs spring-boot-starter-parent

在Spring Boot项目中&#xff0c;有多种方式来管理和配置依赖&#xff0c;本文将详细解析两种主要的依赖配置方法——通过spring-boot-dependencies与spring-boot-starter-parent&#xff0c;并分析它们各自的优缺点以指导开发者的实际应用。 1. spring-boot-dependencies 的使…