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

C++ 20 协程(二)

C++ 20 协程(二)

设计目标

  • 高度可伸缩性
  • 高效的恢复和挂起函数操作
  • 与已有设施无缝衔接,没有开销
  • 允许开发者设计协程库,开放高级语义的接口
  • 在禁用异常的环境可以使用

成为协程

一个函数成为一个协程,通过使用以下关键字中的一个

  • co_return
  • co_await
  • co_yield
  • 循环中的co_awaitimage-20220926150955803

区分协程工厂和协程对象

术语协程通常用于协程的两个方面:一个是调用了co_awaitco_yieldco_return的函数,另一个是协程对象

使用一个协程术语形容协程的两个方面会让人糊涂

MyFuture<int> createFuture() {
co_return 2021; }
int main() {
auto fut = createFuture();
std::cout << "fut.get(): " << fut.get() << '\n'; }

函数createFuture是一个协程工厂返回一个协程对象。协程对象时一个可恢复对象,使用协程框架来指定他的行为

协程框架

实现协程的框架包含了20多个函数,一些必须实现,一些必须重写,因此你可以定制协程的功能

一个协程与三个部分相关:

  • promise object
  • coroutine handle
  • coroutine frame

通过coroutine handle协程句柄与promise object进行交互,并将上下文保存在coroutine frame

image-20220926145654224

编译器在协程执行过程中会自动调用这些函数

协程句柄(coroutine handle

协程句柄是一个非拥有的句柄,用于从外部恢复或销毁协程帧(frame)。协程句柄是可恢复函数的一部分。

template <typename T>
struct Generator
{
	struct promise_type;
	using handle_type = std::coroutine_handle<promise_type>;

	Generator(handle_type h): coro(h)
	{
	}

	handle_type coro;

	~Generator()
	{
		if (coro) coro.destroy();
	}

	T getValue()
	{
		return coro.promise().current_value;
	}

	bool next()
	{
		coro.resume();
		return not coro.done();
	}
}

  • 恢复协程执行:coro.resume()
  • 销毁协程:coro.destroy()
  • 检查状态:coro(15行)

协程帧Coroutine Frame

协程帧维持着协程堆内存的分配状态,包含promise_type,协程复制的参数,挂起点的表示,局部变量等

  • 协程的生命周期必须嵌套在调用者的生命周期内
  • 协程的调用者知到协程帧的大小

协程帧的关键是可等待体(**Awaitables **),等待器(Awaiters

相关文章:

  • 客快物流大数据项目(七十八):Hue简介
  • FPGA的电源供电
  • 【牛客刷题-算法】NC31 第一个只出现一次的字符 (哈希表、队列两种解法)
  • Python之人机猜拳游戏
  • Win10 固定IP地址方法
  • Linux 下查看文件系统类型
  • 上传百度文库有什么技巧吗?百度文库上传怎样才能成功
  • 机器学习之手写决策树以及sklearn中的决策树及其可视化
  • C++初识
  • 成都跨境电商开发
  • 无人机 gazebo 仿真---rotors_simulator 功能包介绍
  • LeetCode刷题总结---二分查找详解
  • vue中watch原理浅析
  • Graph Representation Learning Chapter[2]
  • 一个测试岗面了 30 多人,100多个人投简历,真的太卷了,不能再真实了....
  • 2017-08-04 前端日报
  • Centos6.8 使用rpm安装mysql5.7
  • C学习-枚举(九)
  • go语言学习初探(一)
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • JavaScript DOM 10 - 滚动
  • Node项目之评分系统(二)- 数据库设计
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • VuePress 静态网站生成
  • vue学习系列(二)vue-cli
  • 彻底搞懂浏览器Event-loop
  • 多线程 start 和 run 方法到底有什么区别?
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 那些被忽略的 JavaScript 数组方法细节
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 正则表达式小结
  • 第二十章:异步和文件I/O.(二十三)
  • 关于Android全面屏虚拟导航栏的适配总结
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • ​插件化DPI在商用WIFI中的价值
  • #pragam once 和 #ifndef 预编译头
  • #传输# #传输数据判断#
  • (13)Hive调优——动态分区导致的小文件问题
  • (23)Linux的软硬连接
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (a /b)*c的值
  • (LeetCode) T14. Longest Common Prefix
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (三)elasticsearch 源码之启动流程分析
  • (转)shell中括号的特殊用法 linux if多条件判断
  • (转)菜鸟学数据库(三)——存储过程
  • ****Linux下Mysql的安装和配置
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .bashrc在哪里,alias妙用
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .Net环境下的缓存技术介绍
  • .NET项目中存在多个web.config文件时的加载顺序