std::coroutine_handle 是协程的轻量级控制句柄,用于 resume、destroy 或查询已挂起协程;必须从协程内部或 promise 获取,不可默认构造,且 T 必须匹配 promise 类型,生命周期需与协程帧严格对齐。

std::coroutine_handle 是协程的“遥控器”
它不是协程本身,而是一个轻量级句柄,用来手动 resume、destroy 或查询一个已挂起的协程状态。你拿到它,就等于拿到了对那个协程执行流的控制权——但前提是协程已经挂起(比如在 co_await 后暂停),且你持有其合法的 std::coroutine_handle 实例。
怎么拿到有效的 std::coroutine_handle?
不能凭空构造,必须从协程内部或其 promise 对象中获取。常见路径:
- 在
promise_type::get_return_object()里调用std::coroutine_handle返回 handle::from_promise(*this) - 在
await_suspend()回调中,参数std::coroutine_handle就是当前协程的 handle - 通过
std::coroutine_handle手动转换地址(危险,仅限底层调度器等场景)::from_address(ptr)
错误做法:std::coroutine_handle 或默认构造后直接 resume() —— 这是未初始化的空 handle,调用 resume()/destroy() 会未定义行为(通常 crash)。
resume() 和 destroy() 的调用时机很关键
这两个操作都要求 handle 非空且指向一个**尚未被销毁**的协程帧。典型陷阱:
立即学习“C++免费学习笔记(深入)”;
- 协程已运行结束(即执行完函数体或被 co_return/co_yield 后自动销毁),再调用
resume()→ UB - 多次调用
destroy()→ UB(协程帧只能销毁一次) - 在
await_suspend()返回false后,又手动resume()→ 协程可能已被调度器立即恢复,重复 resume 会崩溃
安全做法:总是先检查 h && h.done() == false 再 resume();destroy() 前确保不会再访问该 handle。
为什么类型模板参数不能乱写?
std::coroutine_handle 中的 T 必须与协程 promise 类型一致(通常是 promise_type)。例如:
struct MyPromise { /* ... */ };
MyCoroutine my_coro() { co_return; } // 返回类型隐含 MyPromise
// 正确:
std::coroutine_handle h = /* ... */;
// 错误:
std::coroutine_handle hv = h; // 编译失败:不能隐式转换
std::coroutine_handle hi = h; // 编译失败:类型不匹配
只有 std::coroutine_handle 是通用“无类型”句柄,可用于跨 promise 类型传递(比如调度器统一管理),但它无法访问 promise 成员,且必须由 from_address() 构造,不能直接从 typed handle 转换。
真正难的不是调用 resume(),而是保证 handle 生命周期和协程帧生命周期严格对齐——稍有错位,就是悬垂指针或双重释放。别指望编译器帮你查这个。










