讲师中心 微信公众号
AI工具推荐 视频效率加速

c++协程的底层实现 c++对称与非对称协程【原理】

云静君_4949

云静君_4949

发布时间:2025-12-31 12:13:34

|

865人浏览过

|

来源于php中文网

原创

C++20协程是编译器支持+标准库协作的非对称协程机制,核心为promise、awaiter和coroutine_handle三要素,底层基于状态机与stackless协程帧,不提供对称跳转原语。

c++协程的底层实现 c++对称与非对称协程【原理】

协程在 C++20 中是通过编译器支持 + 标准库协作实现的,它不是语言内置的“运行时调度器”,而是一套可挂起、可恢复的函数机制,其底层本质是状态机 + 堆栈管理 + 编译器生成的控制流跳转代码。C++ 标准只定义了非对称协程(asymmetric coroutine),所谓“对称协程”在标准中并不存在,是其他语言(如 Kotlin、Go)或第三方库(如 libco、Boost.Coroutine2)的概念,需自行模拟。

协程的核心三要素:promise、awaiter、coroutine_handle

C++ 协程的可挂起行为由三个关键组件协同完成:

  • promise 对象:每个协程实例在堆上(或栈上,取决于分配策略)构造一个 promise_type 实例,负责生命周期管理、异常处理、返回值封装、挂起点决策(initial_suspend / final_suspend)等;
  • awaiter 对象:实现 await_ready / await_suspend / await_resume 三个成员函数的对象,决定何时挂起、挂起时做什么(如注册回调、保存上下文)、恢复后返回什么;
  • coroutine_handle:轻量级句柄,指向协程帧(coroutine frame)首地址,用于手动恢复(resume)、销毁(destroy)、查询状态(done);它不拥有资源,仅是访问入口。

协程帧(coroutine frame):编译器生成的状态机内存布局

当你声明一个 co_await / co_yield / co_return 的函数时,编译器会:

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 将函数体拆解为多个状态(state),对应不同挂起点和恢复点;
  • 把局部变量、参数、临时对象、promise 对象、awaiter 对象(若按值捕获)一并打包进一块连续内存——即“协程帧”;
  • 帧头部固定存放 coroutine_handle 可识别的元数据(如 vtable 指针、promise 指针、当前状态码);
  • 默认使用 operator new 分配帧内存(可被自定义 promise::get_return_object_on_allocation 覆盖),也可用 stackful 方式(如 Boost)做栈切换,但标准协程是 stackless(无独立栈,复用调用方栈帧)。

非对称协程:单向控制流与明确的挂起/恢复语义

C++20 协程是典型的非对称设计:

立即学习“C++免费学习笔记(深入)”;

  • 协程只能由“外部”(比如调用者或 awaiter)主动 resume,不能自己直接跳转到另一个协程;
  • co_await 表达式挂起当前协程,并把控制权交还给 awaiter::await_suspend 返回的 handle(通常是调用方或调度器);
  • 没有 yield-to 或 transfer_to 等对称跳转原语;要实现“协程 A 切到协程 B”,必须经由第三方调度器中转(例如 event loop 保存 A 的 handle,再 resume B);
  • 这种设计简化了 ABI 和内存模型,避免栈共享、寄存器保存等复杂问题,也更契合异步 I/O 和 futures 模型。

所谓“对称协程”在 C++ 中如何模拟?

标准不提供,但可通过以下方式逼近:

  • 用 boost::context 或 libco 手动管理栈和寄存器上下文,实现任意协程间跳转(swap_context);
  • 基于 coroutine_handle + 自定义调度器,在 await_suspend 中不返回 void,而是返回另一个协程的 handle,并在调度器中触发 resume;
  • 封装 transfer() 成员函数,内部保存当前 handle,然后 resume 目标 handle,形成逻辑上的“协程 A 主动切到 B”;
  • 注意:这类模拟无法绕过 stackless 限制,若需真正独立栈(stackful),必须脱离标准协程机制,使用汇编或第三方上下文库。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

相关专题

更多
Kotlin协程编程与Spring Boot集成实践
Kotlin协程编程与Spring Boot集成实践

本专题围绕 Kotlin 协程机制展开,深入讲解挂起函数、协程作用域、结构化并发与异常处理机制,并结合 Spring Boot 展示协程在后端开发中的实际应用。内容涵盖异步接口设计、数据库调用优化、线程资源管理以及性能调优策略,帮助开发者构建更加简洁高效的 Kotlin 后端服务架构。

371

2026.02.12

Java Kotlin协程与异步编程实战
Java Kotlin协程与异步编程实战

本专题围绕 Kotlin 协程与异步编程展开,讲解挂起函数、协程作用域、异步任务调度及并发控制方法。通过实际项目案例,帮助开发者提升后端服务性能,实现高效异步任务处理与稳定性保障。

179

2026.04.13

Kotlin Android开发教程大全
Kotlin Android开发教程大全

系统讲解 Google 官方推荐的 Android 开发首选语言 Kotlin 的核心知识与工程实践,涵盖 Kotlin 简洁语法(空安全/数据类/扩展函数/解构声明/作用域函数)与 Java 互操作、集合操作与函数式编程、协程(Coroutines)异步编程(suspend/launch/async/Flow)、Jetpack Compose 声明式 UI 开发(状态管理/组合函数/导航/动画)、MVVM / MVI 架构设计与 Vi

268

2026.06.03

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

636

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

371

2025.11.27

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6167

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2608

2023.08.10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

100

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn