c++中std::promise与协程promise_type是完全不同的机制:前者是中用于线程间单次结果传递的同步工具,后者是用户定义的协程状态机接口契约,二者无任何实现或继承关系。

C++ 没有标准 Promise 对象(不像 JavaScript 或 Python)。你看到的 std::promise 和协程里的 promise_type 是两套完全不同的机制,混用会直接导致理解崩塌。
std::promise 是线程间传递单次结果的工具
std::promise 和 std::future 配对使用,本质是线程安全的“一次写、多次读”通信通道,和协程无关。
- 典型场景:后台线程算完一个值,主线程等它、取结果 —— 用
std::promise::set_value()写,std::future::get()读 - 不能重复 set:第二次调用
set_value()或set_exception()会抛std::future_error(错误码std::future_errc::promise_already_satisfied) - 没 set 就 get:会阻塞,直到被满足或超时;若 promise 被析构而未 set,
get()抛std::future_error(no_state) - 别把它当“协程返回值容器”:它不参与挂起/恢复逻辑,也不生成状态机
协程的 promise_type 是编译器生成状态机的接口契约
当你写 co_await、co_return,编译器会在后台生成一个状态机类,而这个类必须嵌套定义 promise_type —— 它不是库类型,是你自己写的结构体/类。
- 必须提供
get_return_object():决定协程函数返回什么(比如Task<int></int>),这个对象里通常持有一个指向状态机的指针 - 必须提供
initial_suspend():返回std::suspend_always或std::suspend_never,控制协程启动时是否立刻挂起 - 必须提供
final_suspend():决定协程结束前是否挂起(影响资源清理时机,漏掉会导致析构未执行) -
unhandled_exception()不可少:否则协程内抛异常会直接 terminate - 别试图在
promise_type里存大对象:它被分配在协程帧(stack-like memory)上,生命周期由编译器管理,手动 new 容易泄漏
为什么有人把两者都叫 “Promise”?
纯属术语迁移造成的混淆。std::promise 借用了并发编程中“承诺交付结果”的比喻;而协程 promise_type 是沿用自早期 C++20 协程提案的设计命名,强调“为协程行为做出承诺(提供必要接口)”。二者既无继承关系,也无实现交集。
立即学习“C++免费学习笔记(深入)”;
- 查文档时注意上下文:
std::promise在<future></future>头文件;协程promise_type必须由你定义,且只在co_await函数签名后隐式触发 - 调试协程卡死?先检查
final_suspend()返回了什么 —— 返回std::suspend_always但没手动resume(),协程就永远停在那里 - 想让协程返回值能被外部等待?得自己组合:用
std::promise包裹协程结果,再在return_value()里调用set_value(),但这已是应用层桥接,非语言机制
真正难的不是写对 promise_type 的函数签名,而是理解哪些成员函数会被编译器在什么时机调用、在哪条执行路径上 —— 这些细节没有运行时提示,错一点,协程就静默失效或崩溃。









