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

相关推荐
郭涤生7 小时前
The whole book test_《C++20Get the details》_notes
开发语言·c++·笔记·c++20
郭涤生9 小时前
Chapter 6: Concurrency in C++20_《C++20Get the details》_notes
开发语言·c++·笔记·c++20
BanyeBirth1 天前
C++2025年3月等级考试试题(部分)
c++20
点云SLAM2 天前
C++20新增内容
c++·算法·c++20·c++ 标准库
oioihoii3 天前
C++20 的新工具:std::midpoint 和 std::lerp
c++20
郭涤生5 天前
Chapter 1: Historical Context_《C++20Get the details》_notes
开发语言·c++20
郭涤生5 天前
Chapter 5: The Standard Library (C++20)_《C++20Get the details》_notes
开发语言·c++·笔记·c++20
woodWu6 天前
白话kotlin协程
协程
oioihoii9 天前
深入解析 C++20 中的 std::bind_front:高效函数绑定与参数前置
java·算法·c++20