使用C++20 协程实现异步 I/O 的简易框架

在传统的同步阻塞 I/O 中,线程在等待 I/O 完成期间会被挂起,导致资源利用率低下。随着 C++20 标准引入协程(co_awaitco_return 等关键字),我们可以在单线程或少量线程内实现真正的非阻塞异步 I/O。下面给出一个最小化的示例,演示如何使用 boost::asio(因为它已经原生支持协程)配合 C++20 协程来实现一个 HTTP GET 请求。


1. 准备工作

  1. 编译器:需要支持 C++20 的编译器,例如 GCC 11+ 或 Clang 13+。
  2. 依赖:安装 boost,特别是 boost::asio
  3. 链接:链接 boost_systemboost_coroutine
# Debian/Ubuntu
sudo apt-get install libboost-all-dev

2. 协程包装器

Boost.Asio 已经提供了 `boost::asio::awaitable

`,它封装了协程上下文和异步操作。我们通过 `co_spawn` 启动协程,并使用 `co_await` 进行异步等待。 “`cpp #include #include #include #include #include #include #include namespace asio = boost::asio; using tcp = asio::ip::tcp; using namespace std::chrono_literals; // 简单的协程包装器:等待给定秒数后打印消息 asio::awaitable delay_print(std::string msg, std::chrono::seconds wait) { asio::steady_timer timer{co_await asio::this_coro::executor, wait}; co_await timer.async_wait(asio::use_awaitable); std::cout http_get(const std::string& host, const std::string& path) { auto executor = co_await asio::this_coro::executor; // 1. 解析域名 tcp::resolver resolver{executor}; auto endpoints = co_await resolver.async_resolve(host, “http”, asio::use_awaitable); // 2. 建立连接 tcp::socket socket{executor}; co_await asio::async_connect(socket, endpoints, asio::use_awaitable); // 3. 发送 HTTP GET 请求 std::string request = “GET ” + path + ” HTTP/1.1\r\n” “Host: ” + host + “\r\n” “Connection: close\r\n\r\n”; co_await asio::async_write(socket, asio::buffer(request), asio::use_awaitable); // 4. 读取响应 asio::streambuf response; std::ostringstream ss; for (;;) { std::size_t n = co_await asio::async_read(socket, response.prepare(1024), asio::transfer_at_least(1), asio::use_awaitable); response.commit(n); std::istream is(&response); ss **说明**:上面的 `for (;;)` 循环在实际使用中会抛出 `boost::system::system_error`(`boost::asio::error::eof`)表示连接已关闭。你可以捕获该异常并返回已收集的数据。 — ## 4. 主函数 “`cpp int main() { asio::io_context io_ctx{1}; // 启动协程 asio::co_spawn(io_ctx, []() -> asio::awaitable { try { std::string body = co_await http_get(“example.com”, “/”); std::cout

发表评论