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

相关推荐
yueqc12 天前
Kotlin 协程 Flow 操作符总结
kotlin·协程·flow
charlie1145141918 天前
精读C++20设计模式:行为型设计模式:中介者模式
c++·学习·设计模式·c++20·中介者模式
charlie11451419110 天前
理解C++20的革命特性——协程引用之——利用协程做一个迷你的Echo Server
网络·学习·socket·c++20·协程·epoll·raii
charlie11451419110 天前
理解C++20的革命特性——协程支持2:编写简单的协程调度器
c++·学习·算法·设计模式·c++20·协程·调度器
charlie11451419111 天前
精读C++20设计模式——结构型设计模式:外观模式
c++·学习·设计模式·c++20·外观模式
渡我白衣12 天前
C++ :std::bind 还能用吗?它和 Lambda 有什么区别?
开发语言·c++·c++20
charlie11451419112 天前
理解C++20的革命特性——协程支持1
c++·学习·c++20·协程·语言特性·调度·现代c++
渡我白衣12 天前
C++20 协程:在 AI 推理引擎中的深度应用
大数据·人工智能·c++20
charlie11451419112 天前
精读 C++20 设计模式:行为型设计模式 — 访问者模式
c++·学习·设计模式·访问者模式·c++20
charlie11451419114 天前
精读C++20设计模式——行为型设计模式:命令模式
c++·学习·设计模式·程序设计·命令模式·c++20