C++20 引入了協程(Coroutines),這是一種特殊的函數,它可以暫停執行并在之后恢復,而不是像普通函數那樣一旦返回就終止。協程的主要特點在于它能保留自身的執行狀態,這讓異步編程更加簡潔和直觀。以下是對 C++20 協程的詳細介紹:
關鍵概念
co_await
:這是一個操作符,用于暫停協程的執行,直至等待的異步操作完成。當異步操作完成后,協程會恢復執行。co_yield
:此操作符用于暫停協程的執行,并返回一個值給調用者。協程之后可以繼續執行。co_return
:該操作符用于終止協程的執行,并返回一個值給調用者。
示例代碼
下面的代碼展示了一個簡單的 C++20 協程示例:
#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
}
代碼解釋
Task
?結構體:它是協程的返回類型,包含了?promise_type
?結構體,用于定義協程的行為。coroutineFunction
?函數:這是一個協程函數,使用?co_await std::suspend_always{}
?來暫停協程的執行,然后使用?co_return 42
?來終止協程并返回值 42。main
?函數:調用?coroutineFunction
?函數獲取協程對象,然后調用?get
?方法獲取協程的返回值并輸出。
這個示例只是一個簡單的演示,在實際應用中,協程通常會用于處理異步 I/O 操作,以提高程序的性能和響應能力。