当前位置:网站首页 > 技术博客 > 正文

无栈协程原理



上一篇我们讲解了协程实现的多种方式,但是我们没有讲解协程的分类。在此我们讲解下。

  • 非对称协程(asymmetric coroutines):是跟一个特定的调用者绑定的,协程让出CPU时,只能让回给原调用者。
  • 对称协程(symmetric coroutines):则不同,被调协程启动之后就跟之前运行的协程没有任何关系了。

协程就是一个可以挂起执行,稍后再恢复执行的函数。只要一个函数包含 co_await、co_yield 或 co_return 关键字,则它就是协程。

C++20 中的协程是无栈式的(stackless),协程挂起时会返回到调用者或恢复者,且恢复执行所需的数据会分开存储,而不放在栈上。

另外再说一点,我看有的文章说c++20协程是非对称协程,也就是说必须返回调用者。但是我们写代码时发现,其实也可以调用其他的,所以对网上的这些说法我持保留意见。

先写一个不能运行的c++20协程协程

之所以我们说不能运行的协程是因为,因为我们上面说了,含有上面三个关键字中的就是协程,但是协程函数返回值的类型,必须是一个自定义类型,并且这个自定义类型需要按照一定的格式来定义。比如上文中的代码MyCoroutine就是我们按照要求自定义的类型。

  • 下面我们写一个完整的挂起。并展示下如何自定义协程的返回类型。

输出

对比代码中的备注,我们知道

  • 协程开始时,在协程的状态对象分配内存后,调用promise_type的构造函数

    struct promise_type

  • 为协程的状态对象分配内存失败时

static auto get_return_object_on_allocation_failure() { return MyCoroutine{ nullptr }; }

  • 构造成功后开始执行

auto get_return_object() { return MyCoroutine{ handle::from_promise(*this) }; }

  • 在以上函数后执行

auto initial_suspend() { return std::suspend_always{}; }

  • 协程结束前执行

auto final_suspend() noexcept { return std::suspend_always{}; }

  • 出现未经处理的异常时执行

void unhandled_exception() { return std::terminate();}

  • co_return 时执行,return_void跟return_value二选一
  • co_yield时执行

auto yield_value(T value ) {this->value=value; return std::suspend_always{}; }

  • coroutine_handle也暴露出多个接口,用于控制协程的行为、获取协程的状态,与promise_type不同的是,promise_type里的接口需要我们填写实现,promise_type里的接口是给编译器调用的。coroutine_handle的接口不需要我们填写实现,我们可以直接调用。

输出如下

  • 以下demo是利用chatGBT写的代码基础上更改而来,(因为chatGBT写的代码编译失败)

我们先参考co_yield和co_return,写一个await的例子。(其实这里并非co_await的真正用法,还有其他的用法)

输出

至于真正的等待器的三个关键字的用法我就不写了,感兴趣的同时可以看bilibili的这个讲解。【C++20 协程(2/2)】可等待体和等待器,or稍微啰嗦的这个博客,因为太啰嗦我没仔细看细节,但是里面讲到了等待器的部分知识。所以还是推荐上面哔哩哔哩的视频up主C++20 协程(2):理解co_await运算符

  • 上一篇: 方波微分电路输出波形
  • 下一篇: linux curses
  • 版权声明


    相关文章:

  • 方波微分电路输出波形2025-09-02 11:00:59
  • 二阶低通滤波器特性分析2025-09-02 11:00:59
  • sscom3.3串口使用说明2025-09-02 11:00:59
  • 运算符重载能带来什么好处2025-09-02 11:00:59
  • http请求头类型2025-09-02 11:00:59
  • linux curses2025-09-02 11:00:59
  • 火鸟字幕官网2025-09-02 11:00:59
  • 迭代器iterator三个方法2025-09-02 11:00:59
  • 安卓自定义seekbar2025-09-02 11:00:59
  • mysql内置函数应用2025-09-02 11:00:59