Coroutine(協程)
ll/api/coro/ · 通用
概述
Coroutine 模塊提供了 C++20 協程基礎設施,用於 LeviLamina 中的異步編程。包括協程任務(CoroTask<T>)、生成器(Generator<T>)、執行器和用於 sleep/yield 操作的 awaiter。
頭文件
| 頭文件 | 說明 |
|---|---|
ll/api/coro/CoroTask.h | 協程任務句柄 |
ll/api/coro/CoroPromise.h | CoroTask 的 Promise 實現 |
ll/api/coro/CoroTaskAwaiter.h | 任務 awaiter 內部實現 |
ll/api/coro/Generator.h | 惰性序列生成器 |
ll/api/coro/Executor.h | 抽象工作執行器基類 |
ll/api/coro/SleepAwaiter.h | 異步休眠 awaiter |
ll/api/coro/YieldAwaiter.h | 讓出執行 awaiter |
ll/api/coro/ForwardAwaiter.h | 轉發 awaiter |
ll/api/coro/Collect.h | 收集多個協程結果 |
核心類
CoroTask<T>
協程任務句柄,主要的異步返回類型。
C++
namespace ll::coro {
template <class T = void>
class CoroTask {
public:
using Result = T;
using ExpectedResult = Expected<T>; // void 时为 Expected<>
bool done() const;
void setExecutor(ExecutorRef ex);
ExecutorRef getExecutor();
// co_await 获取值(出错时抛异常)
auto operator co_await(); // -> ValueAwaiter
// co_await 获取 Expected<T>(从不抛异常)
auto tryGet(); // -> ExpectedAwaiter
// 在执行器上启动并回调
template <std::invocable<ExpectedResult> F>
void launch(NonNullExecutorRef executor, F&& callback) noexcept;
void launch(NonNullExecutorRef executor) noexcept;
// 同步阻塞启动
ExpectedResult syncLaunch(NonNullExecutorRef executor) noexcept;
};
}Generator<T>
惰性序列生成器,使用 co_yield 按需產生值。
C++
namespace ll::coro {
template <class T>
struct Generator {
struct iterator; // input_iterator
iterator begin();
iterator end() noexcept;
};
}Executor
調度協程工作的抽象基類。
C++
namespace ll::coro {
class Executor {
public:
virtual void execute(std::function<void()>) const = 0;
virtual std::shared_ptr<data::CancellableCallback> executeAfter(
std::function<void()>, Duration
) const = 0;
};
}使用方法
基本協程任務
C++
#include "ll/api/coro/CoroTask.h"
#include "ll/api/thread/ThreadPoolExecutor.h"
ll::coro::CoroTask<int> computeAsync() {
// 模拟异步工作
co_return 42;
}
void example() {
auto task = computeAsync();
auto result = task.syncLaunch(ll::thread::ThreadPoolExecutor::getDefault());
if (result) {
// result.value() == 42
}
}鏈式協程
C++
#include "ll/api/coro/CoroTask.h"
ll::coro::CoroTask<int> fetchData() {
co_return 100;
}
ll::coro::CoroTask<std::string> processData() {
int data = co_await fetchData();
co_return std::to_string(data);
}使用 tryGet 進行錯誤處理
C++
#include "ll/api/coro/CoroTask.h"
ll::coro::CoroTask<int> mightFail() {
throw std::runtime_error("出了点问题");
co_return 0;
}
ll::coro::CoroTask<> safeProcess() {
auto result = co_await mightFail().tryGet();
if (!result) {
// 无异常地处理错误
}
}生成器
C++
#include "ll/api/coro/Generator.h"
ll::coro::Generator<int> range(int start, int end) {
for (int i = start; i < end; ++i) {
co_yield i;
}
}
void example() {
for (auto val : range(0, 10)) {
// val = 0, 1, 2, ..., 9
}
}帶回調啟動
C++
#include "ll/api/coro/CoroTask.h"
#include "ll/api/thread/ThreadPoolExecutor.h"
ll::coro::CoroTask<int> asyncWork() {
co_return 42;
}
void launchExample() {
asyncWork().launch(
ll::thread::ThreadPoolExecutor::getDefault(),
[](ll::Expected<int> result) {
if (result) {
// 使用 *result
}
}
);
}收集多個任務
C++
#include "ll/api/coro/CoroTask.h"
ll::coro::CoroTask<int> taskA() { co_return 1; }
ll::coro::CoroTask<int> taskB() { co_return 2; }
ll::coro::CoroTask<> collectExample() {
auto [a, b] = co_await ll::coro::collectAll(taskA(), taskB());
// a 和 b 的类型是 Expected<int>
}相關模塊
- Thread(線程工具) —
ThreadPoolExecutor和ServerThreadExecutor實現了Executor - 操作指南:協程 — 分步教程