拆开 Hical:Vyukov MPSC 无锁队列在 HTTP 服务器上的实战——GenericConnection 写路径
[Hical] Vyukov MPSC 无锁队列在 HTTP 服务器上的实战:GenericConnection 的写路径 本专栏文章:拆开 Hical · 第 4 篇 前面三篇都在 HTTP 层面打转——请求怎么解析、路由怎么匹配、中间件怎么执行。这一篇沉到网络层,看一个具体的问题:多个协程想往同一个 socket 写数据时,怎么不加锁? 答案藏在 GenericConnection 的 Vyukov MPSC 无锁队列里。 1. 问题:多个协程同时往一个连接上写 先搞清楚为什么会有这个问题。HTTP/2 和 WebSocket 都允许在一个 TCP 连接上并发地处理多个"流": 1 2 3 线程 A(协程处理 WebSocket frame)──→ 想往 socket 写数据 线程 B(协程处理心跳 ping) ──→ 也想往 socket 写数据 线程 C(IO 线程正在写上一批数据) ──→ socket 只能同时一个写操作 传统的做法是 std::mutex + std::queue。但这里有三个痛点: 生产者多、消费者一个:多个协程往队列里塞数据,只有一个写协程取出来发给 socket mutex 竞争:每秒几十万次 send → 几十万次 mutex lock/unlock → 内核态的 futex 开销 队列长度短:大多数时候队列深度 < 5,争锁的开销比实际写数据还大 2. Vyukov MPSC 队列:核心原理 Dmitry Vyukov 的 MPSC 队列专门为"多生产者、单消费者"场景设计。先直观理解——想象排队买票: ...