首页 > 后端开发 > C++ > 正文

C++如何实现一个简单的协程_C++协程基础与异步编程实现

冰火之心
发布: 2025-11-22 08:40:02
原创
287人浏览过
C++20协程通过co_await、co_yield、co_return关键字实现函数暂停与恢复,核心组件包括promise_type、coroutine_handle和awaitable对象。示例展示协程创建、暂停及通过句柄恢复执行,适用于异步编程如网络请求,提升代码可读性与效率。

c++如何实现一个简单的协程_c++协程基础与异步编程实现

协程(Coroutine)是C++20引入的重要特性,它允许函数在执行过程中暂停并恢复,非常适合处理异步操作,比如网络请求、文件读写等。与线程不同,协程是用户态的轻量级执行单元,开销更小,调度更灵活。

理解C++协程的基本概念

C++中的协程不是像Python那样通过关键字直接定义,而是通过编译器识别特定函数形式来启用。一个函数只要使用了co_awaitco_yieldco_return,就会被当作协程处理。

协程的核心组件包括:

  • Promise Type:控制协程的行为,如返回值、异常处理和暂停逻辑
  • Coroutine Handle:用于手动管理协程的生命周期和恢复执行
  • Awaitable/Awaiter:定义可等待对象的行为,决定何时暂停或继续

这些机制由编译器自动生成框架,开发者需要实现部分接口以满足需求。

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

实现一个简单的协程示例

下面是一个最简化的协程例子,展示如何创建并运行一个可暂停的协程:

#include <coroutine>
#include <iostream>

struct SimpleTask {
   struct promise_type {
      SimpleTask get_return_object() { return {}; }
      std::suspend_never initial_suspend() { return {}; }
      std::suspend_never final_suspend() noexcept { return {}; }
      void return_void() {}
      void unhandled_exception() {}
   };
};

SimpleTask hello_coroutine() {
   std::cout << "Hello from coroutine\n";
   co_await std::suspend_always{};
   std::cout << "Resumed coroutine\n";
}

int main() {
   auto coro = hello_coroutine();
   // 协程已经执行到 co_await 处暂停
   // 这里可以做其他事情
   return 0;
}

在这个例子中,hello_coroutine 函数开始执行后打印第一行,然后遇到 co_await std::suspend_always{} 暂停。但由于我们没有保存协程句柄,也无法恢复它,所以第二条输出不会被执行。

MacsMind
MacsMind

电商AI超级智能客服

MacsMind 131
查看详情 MacsMind

如何恢复协程执行

要真正控制协程的暂停与恢复,需要用到 std::coroutine_handle。修改上面的例子,加入句柄管理:

#include <coroutine>
#include <iostream>

struct ResumableTask {
   struct promise_type {
      ResumableTask get_return_object() {
         return {std::coroutine_handle<promise_type>::from_promise(*this)};
      }
      std::suspend_always initial_suspend() { return {}; }
      std::suspend_always final_suspend() noexcept { return {}; }
      void return_void() {}
      void unhandled_exception() {}
   };

   std::coroutine_handle<promise_type> h_;
   explicit ResumableTask(std::coroutine_handle<promise_type> h) : h_(h) {}
   ~ResumableTask() { if (h_) h_.destroy(); }
   void resume() { if (h_ && !h_.done()) h_.resume(); }
};

ResumableTask my_coroutine() {
   std::cout << "Started\n";
   co_await std::suspend_always{};
   std::cout << "Resumed\n";
}

int main() {
   auto t = my_coroutine(); // 创建协程,但尚未运行
   t.resume(); // 第一次恢复:输出 "Started"
   t.resume(); // 第二次恢复:输出 "Resumed"
   return 0;
}

这次我们通过 get_return_object() 返回包含句柄的对象,并提供 resume() 方法来主动恢复执行。注意 initial_suspend 设置为 suspend_always,确保协程创建后处于暂停状态,直到手动恢复。

协程在异步编程中的应用思路

协程真正的价值体现在异步编程中。设想一个网络请求场景:传统回调方式容易导致“回调地狱”,而协程可以让异步代码看起来像同步一样清晰。

例如,可以设计一个可等待的 future 类型:

  • 当数据未就绪时,协程自动挂起
  • IO 完成后通过回调唤醒协程继续执行
  • 使用 co_await 直接获取结果,无需嵌套 lambda

虽然标准库目前对高层异步支持有限,但像 cppcoroBoost.Asio 等第三方库已提供成熟的异步协程工具集。

基本上就这些。掌握协程的关键在于理解其状态机本质和生命周期管理。从简单任务开始,逐步构建对 promise、awaiter 和调度的理解,才能真正用好C++协程进行高效异步开发。

以上就是C++如何实现一个简单的协程_C++协程基础与异步编程实现的详细内容,更多请关注php中文网其它相关文章!

编程速学教程(入门课程)
编程速学教程(入门课程)

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

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号