异步任务与等待器类型
使用自定义等待器类型和 promise 类型组合异步任务
异步任务与等待器类型 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。
异步协程
异步任务会在 I/O 操作期间暂停,并在操作完成后恢复。将 co_await 与异步 API 结合使用,即可编写无需回调的异步代码。
Task 类型示意图
Task 封装了一个异步协程,并支持使用 co_await 进行链式调用。
template <typename T>
struct Task {
struct promise_type;
std::coroutine_handle<promise_type> handle;
// ...
};co_await 的机制
当编译器看到 co_await expr 时,它要求 expr 是一个可等待对象。可等待对象包含三个方法:
await_ready()— 返回 false 表示暂停,返回 true 表示跳过暂停await_suspend(handle)— 指定暂停期间要执行的操作await_resume()— 指定要交给调用代码的值
可等待对象示例:Sleep
一种会安排在延迟后恢复执行的可等待对象。
struct Sleep {
std::chrono::milliseconds duration;
bool await_ready() const { return false; }
void await_suspend(std::coroutine_handle<> h) {
std::thread([h, this] {
std::this_thread::sleep_for(duration);
h.resume();
}).detach();
}
void await_resume() {}
};
Task<void> example() {
co_await Sleep{500ms};
std::cout << "after 500ms";
}用于 HTTP 的可等待对象
库为 HTTP 请求、计时器和文件 I/O 提供的可等待对象。您可以像使用同步调用一样组合它们。
Task<std::string> fetch() {
auto data = co_await http_get("/api/data");
co_return data;
}组合任务
在一个任务中等待另一个任务,就可以将它们串联起来。外层任务会暂停,直到内层任务完成。
Task<int> outer() {
int x = co_await inner_a();
int y = co_await inner_b();
co_return x + y;
}并行任务
对于并行异步工作,请先启动任务,不要立即逐个等待,然后再等待它们全部完成。
Task<int> sum_tasks() {
auto a = inner_a();
auto b = inner_b();
int x = co_await a;
int y = co_await b;
co_return x + y;
}异常传播
异步任务中抛出的异常可以捕获到 promise 的 unhandled_exception 中,并在等待方重新抛出。
取消
标准库目前还没有提供取消原语。库(cppcoro、boost.cobalt)会自行构建取消机制,通常通过取消令牌或停止源实现。
Boost.Asio 集成
Asio 原生支持协程。您可以对 async_read、async_write 和类似操作使用 co_await。这是目前最简洁的 C++ 异步 I/O 方案。
性能
恢复协程的开销远低于切换线程。编译器通常会将状态机的一部分内联。请进行性能分析,以确认您的可等待对象调用链能够顺利编译。
未来方向
C++23 加入了 std::generator 并带来了一些改进。C++26 可能会引入 std::execution(发送方/接收方),这是一种更通用的异步框架,并可与协程互操作。
快速检查
可等待类型需要哪三个方法?
小结
异步任务将 co_await 与可等待对象结合起来,从而编写无需回调的异步代码。可等待对象包含 await_ready、await_suspend 和 await_resume。库(cppcoro、Asio)提供现成的任务和可等待对象类型。
常见问题解答
「异步任务与等待器类型」课时是免费的吗?
是的 — 「异步任务与等待器类型」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。
「异步任务与等待器类型」这节课中我会学到什么?
使用自定义等待器类型和 promise 类型组合异步任务 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C++ Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「异步任务与等待器类型」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C++ Academy 课中编写并运行代码吗?
能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。