0

0

c++的co_await和co_yield在协程中分别扮演什么角色? (异步编程)

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-14 16:15:09

|

280人浏览过

|

来源于php中文网

原创

co_await用于挂起协程等待异步操作完成,触发await_ready/await_suspend/await_resume协议;co_yield用于generator中产出值并挂起,是promise.yield_value的语法糖。

c++的co_await和co_yield在协程中分别扮演什么角色? (异步编程)

co_await 用于挂起并等待异步操作完成

co_await 的核心作用是把当前协程暂停,交出控制权,等某个 awaitable 对象(比如 std::future、自定义的 awaiter)就绪后再恢复执行。它不是简单“等”,而是触发一整套挂起/恢复协议:调用 await_ready 判断是否可立即返回,否则调用 await_suspend 注册恢复逻辑,最后通过 await_resume 取回结果。

常见错误现象包括:

  • 对非 awaitable 类型(如普通 int)使用 co_await,编译报错 no matching function for call to 'operator co_await'
  • 忘记在 await_suspend 中正确传递 coroutine_handle,导致协程永远不恢复
  • await_resume 中抛异常但没处理,引发未捕获异常终止

典型使用场景是等待 I/O 或定时器:

task<int> fetch_data() {
    auto res = co_await http_get("https://api.example.com/data"); // 挂起,等网络响应
    co_return res.status_code;
}

co_yield 用于向协程生成器输出值并挂起

co_yield 只在 generator<t></t> 这类协程类型中合法,它的本质是 co_await promise.yield_value(value) 的语法糖。每次执行 co_yield x,协程就把 x 交给调用方(比如 for-range 循环),然后挂起,等待下一次迭代时被唤醒。

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

关键点:

Q.AI视频生成工具
Q.AI视频生成工具

支持一分钟生成专业级短视频,多种生成方式,AI视频脚本,在线云编辑,画面自由替换,热门配音媲美真人音色,更多强大功能尽在QAI

下载
  • 不能在返回类型为 taskvoid 的协程里用 co_yield,否则编译失败
  • co_yield 不负责调度,也不等外部事件;它只是“产出 + 挂起”,恢复时机由调用方控制(如 ++it
  • 如果 yield_value 返回 void,协程挂起后无法被唤醒,容易卡死

示例:

generator<int> fib(int n) {
    int a = 0, b = 1;
    for (int i = 0; i < n; ++i) {
        co_yield a;
        int next = a + b;
        a = b;
        b = next;
    }
}

co_await 和 co_yield 的底层行为差异

二者都依赖协程 promise 类型的成员函数,但触发路径不同:

  • co_await expr → 调用 expr.operator co_await() → 最终调用 promise.await_transform / await_ready
  • co_yield val → 展开为 co_await promise.yield_value(val) → 所以必须确保 promise.yield_value 返回一个 awaitable

性能上:co_await 可能引入调度延迟(如线程切换),而 co_yield 通常只是保存+跳转,开销更低;但两者都避免了传统回调嵌套,提升可读性。

兼容性注意:co_yield 在 C++20 中要求编译器支持 generator(如 MSVC 19.3x+、Clang 16+),GCC 13 才开始实验性支持;co_await 支持稍早,但 awaitable 实现仍需谨慎适配 ABI。

容易混淆的边界情况

最常被忽略的是协程类型与关键字的绑定关系:

  • task<t></t> 协程却误用 co_yield:编译器报错 'co_yield' cannot be used in a coroutine that does not support yielding
  • generator<t></t> 却只用 co_await 不用 co_yield:协程变成单次执行,失去“迭代器”语义
  • co_await 表达式里调用一个返回 generator 的函数,却不遍历它:只是构造了一个未启动的 generator 对象,不会触发任何协程逻辑

真正要记住的不是语法,而是每个关键字背后绑定的 promise 接口契约——一旦 promise 缺少对应成员,编译就断在那儿,没有运行时妥协余地。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

970

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

605

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

294

2025.08.29

C++中int的含义
C++中int的含义

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

212

2025.08.29

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

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

186

2023.11.23

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

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

130

2025.11.27

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1848

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

614

2025.10.17

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

23

2026.03.06

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号