讲师中心 微信公众号

工具推荐

视频效率加速
Laper
Laper

剧本策划到成片协作

Seko
Seko

AI短剧一键生成成片

立刻MV
立刻MV

低成本歌曲 MV、视频生成

AniShort
AniShort

AI短剧协同制作平台

c++ c++20协程切换 c++ co_await如何挂起和恢复协程

阿磊大大_5182

阿磊大大_5182

发布时间:2026-03-20 23:51:01

|

986人浏览过

|

来源于php中文网

原创

co_await挂起时保存栈帧到promise_type对象并跳转至awaiter::await_suspend(),其返回值决定后续调度;若返回true需确保coroutine_handle生命周期覆盖恢复全程。

c++ c++20协程切换 c++ co_await如何挂起和恢复协程

co_await 挂起时到底发生了什么

协程挂起不是“暂停执行”,而是保存当前栈帧(局部变量、寄存器状态)到一个堆分配的 promise_type 关联对象里,然后跳转回 awaiter 的 await_suspend()。如果它返回 void 或 bool(且为 false),协程就真停住了;如果返回另一个协程句柄(比如 std::coroutine_handle),调度器会立刻恢复那个协程。

  • 常见错误:自定义 awaiter 的 await_suspend() 忘记返回值,导致编译失败或未定义行为
  • 关键点:await_suspend() 是唯一能决定“挂起后去哪”的地方,不是 await_ready() 决定是否挂起,而是它决定挂起后怎么跳
  • 性能影响:每次 co_await 至少一次虚函数调用(如果 awaiter 是多态)+ 一次堆内存写入(保存 promise 状态),高频 await 会明显拖慢

为什么 co_await 后没进 await_resume 就崩溃了

崩溃往往发生在 await_suspend() 返回 true(表示手动接管调度)之后,但你没确保被挂起的协程 handle 在恢复前一直有效——比如把它存在栈上、或者在恢复前就被 destroy() 了。

  • 典型场景:在 lambda 里捕获 std::coroutine_handle 并传给线程池,lambda 执行完就销毁 handle,线程池 later 调用 resume() 时访问野指针
  • 正确做法:把 handle 存到堆对象里(比如 std::shared_ptr 包裹的结构体),或确保其生命周期覆盖整个异步流程
  • 调试技巧:在 await_suspend() 里打日志,在 await_resume() 前加断点,确认 handle 是否被重复 resume 或已 destroy

std::suspend_always 和 std::suspend_never 的实际区别

它们只是两个预定义的 awaiter 类型,核心差异只在 await_ready() 返回值:suspend_always::await_ready() 总返回 false,强制挂起;suspend_never 总返回 true,跳过挂起直接进 await_resume()。

C++14
C++14

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

下载
  • 别误用:suspend_never 不等于“同步执行”,它只是跳过挂起逻辑,但 await_resume() 仍会被调,且此时协程仍在当前线程上下文中
  • 兼容性注意:C++20 标准库只保证这两个类型有标准定义,其他类似功能必须自己实现,不能依赖第三方头文件里的同名类型
  • 参数差异:二者都不带状态,没有构造参数,也不能传参进去;想带数据得自己写 awaiter 类,重载 operator co_await

协程恢复后局部变量值“变回初始值”

这不是 bug,是 C++ 协程规范要求:每次挂起后恢复,函数作用域内的局部变量(非 static、非引用捕获)都会被析构再重建——因为协程可能跨线程、跨栈恢复,C++ 不保证原栈帧还存在。

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

  • 真实现象:比如 int x = 42; co_await something; printf("%d", x); 输出可能是随机值或 0,不是 42
  • 解决方法:把需要保持的状态存在 promise_type 成员里,或用 static / thread_local(慎用)/ 智能指针堆分配
  • 容易踩的坑:lambda 捕获局部变量(如 [x]() mutable { ... }),挂起后恢复时 x 已被析构,访问即 UB

协程切换的本质是控制流转移 + 状态快照,不是线程切换,也不等价于 setjmp/longjmp;所有“意外丢失状态”的问题,基本都源于混淆了栈生命周期和协程生命周期。

相关文章

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

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

下载

相关标签:

c++

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

热门AI工具

更多
创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

豆包大模型

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

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

WorkBuddy

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

DeepSeek

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

花生AI
花生AI Hot

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

相关专题

更多
java多态详细介绍
java多态详细介绍

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

375

2025.11.27

printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

948

2023.06.20

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1029

2023.11.28

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

5434

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

5611

2025.07.04

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

5434

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

5611

2025.07.04

string转int
string转int

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

7519

2023.08.02

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

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

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