C++20的协程简介

C++20 引入了协程(Coroutines),这是一种特殊的函数,它可以暂停执行并在之后恢复,而不是像普通函数那样一旦返回就终止。协程的主要特点在于它能保留自身的执行状态,这让异步编程更加简洁和直观。以下是对 C++20 协程的详细介绍:

关键概念

  • co_await:这是一个操作符,用于暂停协程的执行,直至等待的异步操作完成。当异步操作完成后,协程会恢复执行。
  • co_yield:此操作符用于暂停协程的执行,并返回一个值给调用者。协程之后可以继续执行。
  • co_return:该操作符用于终止协程的执行,并返回一个值给调用者。

示例代码

下面的代码展示了一个简单的 C++20 协程示例:

cpp 复制代码
#include <coroutine>
#include <iostream>
#include <stdexcept>

// 生成器类模板
template <typename T>
class Generator {
public:
    struct promise_type {
        T current_value;  // 当前生成的数值

        // 协程初始化时直接挂起(惰性执行)
        std::suspend_always initial_suspend() noexcept { return {}; }
        
        // 协程结束时保持挂起以便获取最终结果
        std::suspend_always final_suspend() noexcept { return {}; }
        
        // 协程返回时调用(无返回值)
        void return_void() noexcept {}
        
        // 处理未捕获的异常
        void unhandled_exception() { throw; }

        // 生成器构造入口
        Generator get_return_object() { 
            return Generator{std::coroutine_handle<promise_type>::from_promise(*this)};
        }

        // 定义 co_yield 行为
        std::suspend_always yield_value(T value) {
            current_value = value;
            return {};
        }
    };

    // 协程句柄
    std::coroutine_handle<promise_type> coro_handle;

    // 构造函数
    explicit Generator(std::coroutine_handle<promise_type> h) : coro_handle(h) {}
    
    // 析构时销毁协程
    ~Generator() { if (coro_handle) coro_handle.destroy(); }

    // 迭代器支持
    bool move_next() {
        if (!coro_handle.done()) {
            coro_handle.resume();
            return !coro_handle.done();
        }
        return false;
    }

    T current() const { return coro_handle.promise().current_value; }

    // 范围遍历支持
    struct Iter {
        Generator& gen;
        bool operator!=(std::nullptr_t) const { return gen.move_next(); }
        void operator++() {}
        T operator*() const { return gen.current(); }
    };

    Iter begin() { return Iter{*this}; }
    std::nullptr_t end() { return nullptr; }
};

// 生成整数序列的协程函数
Generator<int> generate_sequence(int start, int end) {
    for (int i = start; i <= end; ++i) {
        co_yield i;  // 每次生成一个值并挂起
    }
}

int main() {
    // 生成 1 到 10 的序列
    auto seq = generate_sequence(1, 10);
    
    // 遍历输出
    for (auto num : seq) {
        std::cout << num << " ";
    }
    // 输出: 1 2 3 4 5 6 7 8 9 10
}

代码解释

  1. Task 结构体 :它是协程的返回类型,包含了 promise_type 结构体,用于定义协程的行为。
  2. coroutineFunction 函数 :这是一个协程函数,使用 co_await std::suspend_always{} 来暂停协程的执行,然后使用 co_return 42 来终止协程并返回值 42。
  3. main 函数 :调用 coroutineFunction 函数获取协程对象,然后调用 get 方法获取协程的返回值并输出。

这个示例只是一个简单的演示,在实际应用中,协程通常会用于处理异步 I/O 操作,以提高程序的性能和响应能力。

相关推荐
XiaoLeisj12 小时前
Android Kotlin 全链路系统化指南:从基础语法、类型系统与面向对象,到函数式编程、集合操作、协程并发与 Flow 响应式数据流实战
android·开发语言·kotlin·协程
w我是东山啊2 天前
C++20——协程
c++20
wangjialelele3 天前
C++11、C++14、C++17、C++20新特性解析(一)
linux·c语言·开发语言·c++·c++20·visual studio
telllong4 天前
C++20 Modules:从入门到真香
java·前端·c++20
AMoon丶6 天前
Golang--协程调度
linux·开发语言·后端·golang·go·协程·goroutine
带娃的IT创业者7 天前
Python 异步编程完全指南(二):深入 asyncio 核心概念
开发语言·python·协程·事件循环·asyncio·异步编程
PokeMa10 天前
[协程]-[详解]-launch与async
kotlin·async·协程·launch·协程构建·源码对比
PokeMa10 天前
[协程]-[详解]-[协程作用域]-viewModelScope
kotlin·协程·源码分析·viewmodelscope·原理分析·协程作用域
zh_xuan1 个月前
kotlin Flow的用法2
android·开发语言·kotlin·协程·flow·被压
zh_xuan1 个月前
kotlin 测试协程嵌套
android·kotlin·协程