跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

c++中的协程awaiter和awaitable是什么_c++协程自定义与原理【C++20】

awaitable是可被co_await的触发器,通过operator co_await()返回awaiter;awaiter是执行挂起/恢复的执行器,需实现await_ready()、await_suspend()和await_resume()三要素。 在 C++20 中,
awaitable
和
awaiter
是协程(coroutine)机制的核心抽象,它们共同支撑
co_await
表达式的语义,但二者职责不同、层次分明。 awaitable:可等待对象,协程暂停的“触发器”
awaitable
不是某个具体类型,而是一类满足特定要求的对象——它能通过
operator co_await()
返回一个
awaiter
。 标准库 中如
std::suspend_always
、
std::suspend_never
是最简 awaitable;自定义类型只要提供该 operator,就可被
co_await
使用。 常见写法: 直接返回
awaiter
对象(如
return my_awaiter{};
) 返回自身并定义
operator co_await()
(推荐,支持链式 await) 返回代理对象(如包装 future 或 promise 的适配器) awaiter:真正执行挂起/恢复逻辑的“执行器”
awaiter
是一个满足三要素的类型: – 有
await_ready()
:返回
bool
,决定是否跳过挂起(例如立即就绪时返回
true
) – 有
await_suspend(coroutine_handle<> h)
:决定如何挂起协程(可返回 void、bool 或另一个 coroutine_handle) – 有
await_resume()
:协程恢复后执行,通常返回值(或 void),即
co_await expr
的结果 注意:
await_suspend
的返回值很关键: – 返回
void
:挂起后不调度,控制权交还给调用者 – 返回
true
:挂起成功,协程进入暂停状态 – 返回
false
:挂起被拒绝,协程继续执行(相当于没挂起) – 返回
coroutine_handle
:将当前协程移交到该 handle 所指协程(常用于链式调度) 自定义 awaitable + awaiter 的典型流程 以实现一个延时等待为例(模拟 sleep): 立即学习 “ C++免费学习笔记(深入) ”; 豆包Mac版 豆包AI客户端 Mac版凭借其强大的性能与深度的系统融合,成为了Mac用户不可或缺的桌面级智能工具。作为字节跳动公司基于先进的“云雀模型”自主研发的AI工具软件,它不仅仅是一个简单的聊天机器人,更是一个集创作、学习、搜索与系统交互于一体的全能型AI助手。 下载 定义
delay_awaitable
类,含构造函数接收毫秒数 在其中定义
operator co_await()
,返回一个
delay_awaiter
delay_awaiter
存储延迟时间,并在
await_suspend
中启动定时器(如用
std::thread
+
std::this_thread::sleep_for
,或绑定到 event loop) 定时结束后,调用
resume()
恢复原协程(需保存
coroutine_handle
) 关键点:awaiter 必须可移动(通常默认移动语义即可),且生命周期需覆盖挂起期间——不能在 suspend 后析构。 原理本质:编译器生成状态机 + 用户接管控制流 C++ 协程不是运行时调度器,而是编译器把函数重写为状态机(state mac hine)。每次
co_await
都对应一个状态跳转点。 –
awaitable
是用户提供的“接入点”,告诉编译器“这里要切出去” –
awaiter
是用户写的“胶水代码”,负责决定何时切、切到哪、切回来拿什么值 – 所有调度逻辑(线程切换、事件循环唤醒、异常传播等)均由 awaiter 显式控制,标准库不内置调度器 这意味着:C++20 协程轻量、零成本抽象,但也意味着你得自己处理线程安全、内存生命周期、错误传播等——它提供的是能力,不是开箱即用的 async/await。 基本上就这些。理解 awaitable 是“谁可以被等”,awaiter 是“怎么等、等完干啥”,就能稳住协程自定义的主干逻辑。

相关文章