0

0

C++20中的协程(Coroutines)如何使用?(入门代码示例)

裘德小鎮的故事

裘德小鎮的故事

发布时间:2025-12-25 10:42:34

|

393人浏览过

|

来源于php中文网

原创

C++20协程是可挂起恢复的函数,需手动实现promise_type、awaiter和返回类型三要素;示例Generator通过co_yield实现懒加载整数生成,强调initial_suspend、final_suspend及生命周期管理。

c++20中的协程(coroutines)如何使用?(入门代码示例)

协程不是线程,也不启动新执行流,它是一种可挂起、可恢复的函数,用于简化异步逻辑、生成器、状态机等场景。C++20 协程是语言级支持,但需要手动实现协程桩(promise type)、awaiter 和返回类型——不依赖运行时库,但也意味着不能直接“开箱即用”。

基础结构:三要素缺一不可

每个协程必须有:

  • 返回类型:需定义 promise_type 嵌套类,并提供 get_return_object()initial_suspend()final_suspend()return_void()(或 return_value())等接口;
  • 挂起点:使用 co_await 表达式,其操作数需满足 awaiter 要求(含 await_ready()await_suspend()await_resume());
  • 挂起关键词co_return(结束协程)、co_await(挂起等待)、co_yield(挂起并产出值,常用于 generator)。

最简可运行示例:一个懒加载的整数生成器

下面是一个能逐次产出 0、1、2 的协程 generator(类似 Python 的 yield):

// 编译需支持 C++20:g++-11+ / clang++-13+,加 -std=c++20
#include 
#include 
#include 

template
struct Generator {
  struct promise_type;
  using handle_type = std::coroutine_handle

  struct promise_type {
    T current_value;
    auto get_return_object() { return Generator{handle_type::from_promise(*this)}; }
    auto initial_suspend() { return std::suspend_always{}; }
    auto final_suspend() noexcept { return std::suspend_always{}; }
    void return_void() {}
    void unhandled_exception() { std::terminate(); }
    auto yield_value(T value) {
      current_value = value;
      return std::suspend_always{};
    }
  };

  explicit Generator(handle_type h) : coro_(h) {}
  Generator(const Generator&) = delete;
  Generator& operator=(const Generator&) = delete;
  Generator(Generator&& rhs) noexcept : coro_(rhs.coro_) { rhs.coro_ = nullptr; }
  Generator& operator=(Generator&& rhs) noexcept {
    if (this != &rhs) {
      if (coro_) coro_.destroy();
      coro_ = rhs.coro_;
      rhs.coro_ = nullptr;
    }
    return *this;
  }
  ~Generator() { if (coro_) coro_.destroy(); }

  bool next() {
    if (!coro_ || coro_.done()) return false;
    coro_.resume();
    return !coro_.done();
  }
  T value() const { return coro_.promise().current_value; }

private:
  handle_type coro_;
};

Generator counter() {
  co_yield 0;
  co_yield 1;
  co_yield 2;
}

int main() {
  auto g = counter();
  while (g.next()) {
    std::cout << g.value() << '\n';
  }
  // 输出:0\n1\n2
}

关键点说明

这段代码展示了协程最核心的协作模式:

《PHP设计模式指南》中文版
《PHP设计模式指南》中文版

《PHP设计模式》首先介绍了设计模式,讲述了设计模式的使用及重要性,并且详细说明了应用设计模式的场合。接下来,本书通过代码示例介绍了许多设计模式。最后,本书通过全面深入的案例分析说明了如何使用设计模式来计划新的应用程序,如何采用PHP语言编写这些模式,以及如何使用书中介绍的设计模式修正和重构已有的代码块。作者采用专业的、便于使用的格式来介绍相关的概念,自学成才的编程人员与经过更多正规培训的编程人员

下载

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

  • co_yield 触发 promise_type::yield_value(),保存值并挂起;
  • Generator::next() 调用 resume() 恢复执行,直到下次挂起或结束;
  • initial_suspend() 设为 suspend_always,让协程创建后不自动运行(惰性求值);
  • final_suspend() 也设为 suspend_always,防止协程结束后自动销毁 promise,方便外部安全读取结果。

常见误区提醒

初学容易踩坑的地方:

  • 忘记在 ~Generator 中调用 coro_.destroy() → 内存泄漏;
  • 把协程句柄(coroutine_handle)复制多次却不管理生命周期 → 悬空指针;
  • 误以为 co_await 等价于“异步等待” → 它只是语法糖,行为完全由 awaiter 决定(可以立刻返回,也可以调度到线程池);
  • 没处理 unhandled_exception() → 协程内抛异常会导致程序终止。

基本上就这些。协程本身不难理解,难点在于设计清晰的协程类型契约。建议从 generator 入手,再过渡到 async/await 风格的 task 类型(如 Task),逐步掌握 suspend/resume 的控制权。

相关专题

更多
python开发工具
python开发工具

php中文网为大家提供各种python开发工具,好的开发工具,可帮助开发者攻克编程学习中的基础障碍,理解每一行源代码在程序执行时在计算机中的过程。php中文网还为大家带来python相关课程以及相关文章等内容,供大家免费下载使用。

707

2023.06.15

python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

625

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

734

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

616

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

1234

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

573

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

695

2023.08.11

苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

10

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 2.4万人学习

SciPy 教程
SciPy 教程

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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