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

相关推荐
落羽的落羽4 小时前
【C++】现代C++的新特性constexpr,及其在C++14、C++17、C++20中的进化
linux·c++·人工智能·学习·机器学习·c++20·c++40周年
kyle~4 天前
CPU调度---协程
java·linux·服务器·数据库·c++20
deng-c-f12 天前
Linux C/C++ 学习日记(32):协程(二):Ntyco源码解析
学习·协程·ntyco
deng-c-f12 天前
Linux C/C++ 学习日记(35):协程(五):同步、多线程、多协程在IO密集型场景中的性能测试
学习·线程·协程·同步·性能
deng-c-f16 天前
Linux C/C++ 学习日记(30):协程(一):同步和异步、协程的简要介绍、用户态CPU调度的实现
学习·协程·同步/异步
yueqc124 天前
Kotlin 协程 Flow 操作符总结
kotlin·协程·flow
charlie1145141911 个月前
精读C++20设计模式:行为型设计模式:中介者模式
c++·学习·设计模式·c++20·中介者模式
charlie1145141911 个月前
理解C++20的革命特性——协程引用之——利用协程做一个迷你的Echo Server
网络·学习·socket·c++20·协程·epoll·raii
charlie1145141911 个月前
理解C++20的革命特性——协程支持2:编写简单的协程调度器
c++·学习·算法·设计模式·c++20·协程·调度器
charlie1145141911 个月前
精读C++20设计模式——结构型设计模式:外观模式
c++·学习·设计模式·c++20·外观模式