c++20协程无法直接发http请求,因其仅定义挂起/恢复协议,不提供网络io能力;std::coroutine_handle不封装socket/tls/dns,也无标准awaitable实现,硬写伪异步将导致阻塞或需手造io_uring轮子。

不能真正实现——C++20 协程本身不提供网络能力,std::coroutine_handle 不会自动处理 socket、DNS 或 TLS,硬要“不依赖第三方库”写异步 HTTP 请求,结果只能是阻塞式伪协程,或自己重造 io_uring / epoll 轮子。
为什么 std::coroutine 无法直接发 HTTP 请求
std::coroutine 只是一套协议:定义了怎么挂起、怎么恢复、状态存在哪。它不关心你等的是磁盘 IO 还是网络就绪,更不提供 connect()、send()、recv() 的非阻塞封装。常见错误是写这样的代码:
co_await some_blocking_socket.send(data); // ❌ 实际调用阻塞 syscall,整个线程卡死
这类写法看似用了 co_await,但 awaiter 没绑定事件通知机制,协程挂起后没人唤醒它,等于白挂。
- 协程需要可等待对象(
Awaitable)实现await_ready/await_suspend/await_resume - 而
await_suspend必须把协程句柄注册到某个事件驱动层(如 epoll、kqueue、io_uring) - C++ 标准库没提供任何系统级 I/O 的
Awaitable实现
不引入 Boost/Asio,但用 Linux 原生 io_uring 怎么办
如果你坚持“不依赖第三方库”,唯一可行路径是手写 io_uring 的 awaiter —— 但这要求:
- Linux 内核 ≥ 5.11(
IORING_OP_SEND/IORING_OP_RECV稳定支持) - 手动管理
io_uring_sqe提交、io_uring_cqe完成、buffer 生命周期 - 必须用
io_uring_register_buffers预注册内存,否则每次 send/recv 都触发缺页中断 - 协程恢复必须在
io_uring_cqe就绪后由轮询线程或信号驱动调用handle.resume()
示例关键片段(省略错误检查和内存注册):
struct io_uring_awaiter {
int fd_;
void* buf_;
size_t len_;
bool is_read_;
<p>bool await_ready() const { return false; }
void await_suspend(std::coroutine_handle h) {
auto* sqe = io_uring_get<em>sqe(&ring</em>);
if (is<em>read</em>)
io_uring_prep<em>recv(sqe, fd</em>, buf<em>, len</em>, 0);
else
io_uring_prep<em>send(sqe, fd</em>, buf<em>, len</em>, 0);
io_uring_sqe_set_data(sqe, h.address());
io_uring<em>submit(&ring</em>);
}
void await_resume() {}
};</p>
注意:io_uring 不处理 DNS、HTTP 解析、TLS 握手——这些仍得自己实现或调用 getaddrinfo()(同步)、openat()(同步)等,它们无法被 co_await 包装而不阻塞。
编译器和标准库的隐性依赖绕不开
即使你手写了全部 awaiter,以下依赖仍存在:
-
-fcoroutines是 GCC/Clang 特定 flag,不是标准 C++ 行为 -
std::coroutine_traits和std::suspend_always来自<coroutine></coroutine>,属于标准库实现细节 - 链接时需
-ls(GCC)或-lc++experimental(Clang),本质仍是“第三方”运行时支持 - 所有现代
io_uring封装(如 liburing)也属于外部库,纯裸系统调用写法极难维护
所谓“不依赖第三方库”,实际只是把 Boost.Asio 换成自己写的 bug 更多的 Asio 子集。
真正轻量且可用的方案,是接受 boost::beast + boost::asio::use_awaitable —— 它的二进制体积可控,头文件模式可裁剪,且避免了自己管理 fd、buffer、超时、重试、SSL 的所有坑。试图完全零依赖,只会把精力耗在重复造轮子和调试 epoll 边缘 case 上。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











