## C++20 协程:从理论到实践的完整指南

1. 引言

C++20 在语法层面上引入了协程(coroutine)这一强大的功能。它让我们可以以更直观的方式编写异步代码,降低复杂度,提升可读性。本文将从协程的基本概念、关键字、标准库支持以及实际应用案例四个维度进行系统阐述,并给出完整可编译的示例。

2. 协程基础

2.1 什么是协程?

协程是一种可挂起与恢复的函数。与线程不同,协程的调度完全由程序控制,轻量级、无锁化。协程允许在执行过程中暂停(co_awaitco_yieldco_return)并在需要时继续。

2.2 关键字

  • co_await:等待一个协程对象或任何可 await 的值。
  • co_yield:产生一个值,类似生成器。
  • co_return:返回协程结果,终止协程。
  • co_spawn:标准库未提供,通常用第三方库或自己实现。

2.3 协程函数的返回类型

协程函数的返回类型必须是一个协程类型:`std::future

`、`std::generator`、`std::task` 等。编译器根据返回类型决定协程的行为。 ### 3. 标准库支持 | 类型 | 说明 | 示例 | |——|——|——| | `std::future ` | 支持 `co_await` | `std::future f = async_task();` | | `std::generator ` | 支持 `co_yield` | `for (auto v : gen) {…}` | | `std::task `(在《P0208R2》提案) | 通用协程类型 | `std::task t = async_op();` | > **注意**:标准库的 `std::future` 并不完全满足协程需求,推荐使用 `std::experimental::generator` 或第三方实现(如 `cppcoro`、`Boost.Asio`)。 ### 4. 实例:实现一个异步 I/O 的网络客户端 下面演示如何使用 C++20 协程与 `Boost.Asio` 完成一个简单的 TCP 客户端。 “`cpp #include #include #include #include #include using namespace boost::asio; namespace ip = boost::asio::ip; using tcp = ip::tcp; // 协程包装器 template auto async(Func&& f) { return std::async(std::launch::async, std::forward (f)); } // 异步发送字符串 asio::awaitable async_send(tcp::socket& sock, const std::string& msg) { co_await async_write(sock, buffer(msg)); } // 异步接收字符串 asio::awaitable async_receive(tcp::socket& sock) { char data[1024]; std::size_t n = co_await async_read(sock, buffer(data)); std::string res(data, n); co_return res; } int main() { io_context ctx; tcp::resolver resolver(ctx); auto results = resolver.resolve(“127.0.0.1”, “12345”); tcp::socket socket(ctx); boost::asio::async_connect(socket, results, [&](const boost::system::error_code& ec, const tcp::endpoint&) { if (!ec) { std::cout

发表评论