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 操作,以提高程序的性能和响应能力。

相关推荐
OPEN-F3 天前
C++20新特性精讲:概念、范围与三路比较
算法·c++20
小小龙学IT11 天前
C++ std::chrono 时间库深度解析:从 duration 模板到 C++20 日历与时区
linux·c++·c++20
郝学胜-神的一滴13 天前
C++20 高级编程 004:从初始化、内存到const系列关键字
开发语言·算法·编程·软件构建·c++20
可爱系程序猿13 天前
msvcp120.dll 加载失败排查:VC++ 2013、进程架构与插件私有目录如何对应
程序人生·电脑·c++20
ShineWinsu14 天前
对于C++:C++20中线程、初始化、Lambda与内存视图等特性的解析
c++·c++20
可爱系程序猿14 天前
mfc100.dll 加载失败排查:旧版 VC++ 2010 程序、位数与插件目录如何核对
程序人生·电脑·c++20
felixking16 天前
C++20 协程
开发语言·c++·协程
ShineWinsu17 天前
对于 C++:C++20中Concept(概念) 与 Coroutine(协程)的解析
linux·开发语言·网络·c++·c++20·epoll
linweidong21 天前
钉钉Java面经及参考答案
nacos·协程·垃圾收集器·jvm调优·spring ioc·脏读·mysql索引
Lzg_na24 天前
C++20 Concept 核心概念、语法详解与三大工程实践场景
c++20