不能。C++20协程无网络I/O能力,std::coroutine_handle和co_await仅为控制流调度机制,不提供socket、DNS、TLS或事件循环支持,必须依赖系统API或第三方库实现异步HTTP请求。

不能。C++20 协程本身不提供网络 I/O 能力,std::coroutine_handle 和 co_await 只是状态机调度协议,没有 socket、DNS、TLS 或事件循环——你无法绕过操作系统接口完成 HTTP 请求。
为什么 std::coroutine 无法直接发 HTTP 请求
协程挂起/恢复只是控制流切换,不代表 I/O 就绪。真实网络请求必须等待 fd 可读/可写,而标准库不暴露底层 epoll、kqueue 或 IOCP 接口。试图在阻塞 socket 上 co_await 会导致线程卡死;用 std::this_thread::sleep_for 模拟延时则完全失去异步意义。
-
co_await需要一个满足 awaitable 概念的对象,它必须实现await_ready、await_suspend、await_resume - 标准库中没有任何类型实现这些方法来对接 socket I/O
-
std::promise/std::future不可 await(除非手动包装),且仍依赖线程池或阻塞等待
不依赖第三方库的唯一可行路径:系统 API + 手动 awaiter
你得自己封装 epoll(Linux)、kqueue(macOS)或 IOCP(Windows)为 awaitable 对象,并管理 socket 生命周期。这已不是“轻量级”,而是重写半个 ASIO。
- 需手动调用
socket()、connect()、getaddrinfo()、epoll_ctl()等系统调用 - 每个 I/O 操作都要构造一个自定义 awaiter,在
await_suspend中注册到事件循环,并保存std::coroutine_handle - DNS 解析必须用异步方式(如
getaddrinfo_a或线程池+getaddrinfo),否则又会阻塞 - TLS 握手无标准异步接口,OpenSSL 的
SSL_do_handshake返回SSL_ERROR_WANT_READ/WRITE,需反复co_await直到就绪
常见误判:以为 std::jthread 或 std::async 能替代
它们仍是同步阻塞模型:std::async(std::launch::async, [&]{ return http_get(...); }) 启动的是新线程,内部仍是 curl_easy_perform 或 send/recv 阻塞调用——这不是协程异步,只是把阻塞挪到另一条线程上。
立即学习“C++免费学习笔记(深入)”;
-
std::jthread仅管理线程生命周期,不提供 awaitable 接口 -
std::async返回std::future,而std::future::await_ready始终返回false(C++20 标准未要求其实现 awaitable) - 强行给
std::future加 awaiter 包装,本质是轮询wait_for(1ms),CPU 空转且延迟高
真正轻量且不依赖第三方的方案不存在。所谓“不依赖第三方”在协程网络场景下,等价于重写 ASIO/Beast 的核心逻辑。生产环境应直接用 boost::beast::http::async_read 或 async_simple::coro::Lazy——它们已解决 buffer 管理、错误传播、取消语义等所有暗坑。自己造轮子时,最容易被忽略的是:连接超时必须由定时器和 I/O 事件双路驱动,而单靠 std::chrono + co_await 无法做到精确非阻塞等待。


















