C++20协程由返回类型、promise_type和coroutine_handle组成,通过co_await/co_yield/co_return触发,编译器将其转为状态机,实现暂停与恢复。

在C++20中,协程不再是第三方库的专属功能,而是语言原生支持的特性。它允许函数在执行过程中暂停并恢复,而无需阻塞线程。要理解如何实现一个简单的协程,需要先掌握C++20协程的基本结构和核心组件。
协程的三个基本组成部分
C++20协程依赖于三个关键部分:返回类型、promise_type 和协程句柄(coroutine_handle)。只有满足这些条件,编译器才会将函数识别为协程。
返回类型:必须包含嵌套的 promise_type 类型。 promise_type:定义协程的行为,比如初始挂起、最终挂起、返回值处理等。 协程句柄 coroutine_handle:用于手动控制协程的暂停与恢复。
当函数中出现 co_await、co_yield 或 co_return 关键字时,该函数自动成为协程。
实现一个最简单的协程
下面是一个极简但完整的协程示例,展示如何定义一个可挂起并恢复的协程:
立即学习“C++免费学习笔记(深入)”;
#include #include struct SimpleCoroutine { struct promise_type { SimpleCoroutine get_return_object() { return {}; } std::suspend_always initial_suspend() { return {}; } std::suspend_always final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception() {} };};SimpleCoroutine hello_coroutine() { std::cout << "Hello from coroutine!n"; co_await std::suspend_always{};}
这个例子中:
SimpleCoroutine::promise_type 提供了协程所需的所有接口。 initial_suspend 返回 std::suspend_always,表示协程启动后立即挂起。 final_suspend 同样挂起,防止协程结束后自动销毁。 co_await std::suspend_always{} 显式挂起点。
手动控制协程的生命周期
使用 std::coroutine_handle 可以获取对协程状态的直接控制:
int main() { auto coro = hello_coroutine(); // 获取协程句柄(需修改返回对象传递 handle) // 实际中通常在 get_return_object 中构造 handle return 0;}
更实用的做法是让返回类型持有 coroutine_handle:
struct Task { struct promise_type; using handle_type = std::coroutine_handle; struct promise_type { Task get_return_object() { return Task(handle_type::from_promise(*this)); } std::suspend_always initial_suspend() { return {}; } std::suspend_always final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception() {} }; handle_type h_; explicit Task(handle_type h) : h_(h) {} ~Task() { if (h_) h_.destroy(); } void resume() { if (h_ && !h_.done()) h_.resume(); }};
这样就可以在外部调用 resume 来恢复执行:
Task my_coroutine() { std::cout << "Startn"; co_await std::suspend_always{}; std::cout << "Resumed!n";}int main() { Task t = my_coroutine(); t.resume(); // 输出 "Start" t.resume(); // 输出 "Resumed!"}
协程的工作原理简析
C++20协程在编译期被转换成状态机。编译器会将协程拆分为多个帧(frame),其中包含局部变量、当前状态和挂起点信息。
每次调用 co_await 时,会检查是否需要挂起(via await_ready)。 若需挂起,则执行 await_suspend(可传入 coroutine_handle)来安排恢复时机。 通过 await_resume 获取结果。
标准提供了 std::suspend_always 和 std::suspend_never 两种默认awaiter,分别表示总是挂起和从不挂起。
基本上就这些。C++20协程机制灵活但底层,实际使用常配合生成器、异步任务等模式封装。理解其组成和生命周期是构建高效异步程序的基础。
以上就是c++++怎么实现一个简单的协程_c++20协程基础与实现原理解析的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1481506.html
微信扫一扫
支付宝扫一扫