**C++20 协程:在异步 IO 中优雅地使用**

协程是 C++20 引入的一项强大特性,它让异步编程变得像同步编程一样直观。下面我们通过一个简单的网络请求示例,演示如何使用协程实现异步 IO,并讨论常见的陷阱与最佳实践。


1. 协程基础

协程通过 co_yieldco_returnco_await 等关键字实现“暂停”和“恢复”功能。协程函数的返回类型必须是 std::experimental::generator、**`std::experimental::generator

`** 或 **`std::experimental::task`**(后者在标准 C++20 中是 `std::future` 的一个包装)。 “`cpp #include #include #include #include std::future async_http_get(const std::string& url); “` ### 2. 异步 HTTP GET 的协程实现 下面的示例演示如何用协程包装 `std::async`,并在等待期间让线程池或事件循环继续执行其它任务。 “`cpp #include #include #include #include #include #include // 模拟网络请求的耗时操作 std::string fake_http_get(const std::string& url) { std::this_thread::sleep_for(std::chrono::seconds(2)); return “Response from ” + url; } // 把耗时操作包装成协程 std::future async_http_get(const std::string& url) { // 这里用 std::async 来模拟异步操作,真实项目可替换成 ASIO 等库 return std::async(std::launch::async, fake_http_get, url); } // 协程入口 std::future process_requests(const std::vector& urls) { for (const auto& url : urls) { // 发起异步请求 std::future fut = async_http_get(url); // 这里可以做其他工作,例如更新 UI std::cout **注意**:C++20 标准库并没有直接提供 `co_await` 的实现,`std::future` 本身不支持协程。实际使用时应依赖 **`std::experimental::task `** 或第三方库(如 `cppcoro`、`libcoro`、`asio` 的协程适配器)。上例为伪代码,展示思路。 ### 3. 事件循环与协程 在实际项目中,协程往往与事件循环(Event Loop)配合使用。下面是一个简化的事件循环示例,展示如何将协程与 `select`/`epoll` 等 IO 复用机制整合。 “`cpp #include #include #include class EventLoop { public: EventLoop() { epfd_ = epoll_create1(0); } ~EventLoop() { close(epfd_); } void add_fd(int fd, int events) { epoll_event ev{}; ev.events = events; ev.data.fd = fd; epoll_ctl(epfd_, EPOLL_CTL_ADD, fd, &ev); } void run() { while (true) { std::array events; int nfds = epoll_wait(epfd_, events.data(), events.size(), -1); for (int i = 0; i

发表评论