C 语言中的 Go 风格并发
来源:antonz.org — 2026-07-13
📋 概述
作者 Anton Zhiyanov 在其 Solod(So)项目中探索了如何用纯 POSIX 线程(pthreads)在 C 语言中模拟 Go 的并发模型——包括互斥锁、条件变量、原子操作、工作池和通道。核心洞见在于:虽然 pthreads 不支持 Go 那种用户态轻量级调度,但在粗粒度任务场景下性能差距仅约 10%,而原子操作和无竞争锁甚至比 Go 更快。文章通过详细的基准测试数据量化了每种场景下的性能权衡。
🔑 核心要点
- pthreads 为基础:Mutex 封装
pthread_mutex_t,Cond 封装 pthread_cond_t,通道和工作池都建立在这两个原语之上
- 原子操作与 Go 性能持平:Load/Store 均为 2ns,CAS 为 13ns,直接映射到 C 编译器的
__atomic 内建指令
- 无竞争场景下更快:无竞争 Mutex 为 9ns(Go 为 14ns),自旋竞争为 27ns(Go 为 75ns)——原因在于薄封装更贴近硬件
- 有等待时显著变慢:条件变量比 Go 慢 7-10 倍,无缓冲通道比 Go 慢 23 倍——根源在于内核态线程唤醒的 syscall 开销
- 粗粒度任务场景接近 Go:1000 个 CPU 任务的线程池吞吐仅比 Go 慢 1.1x,因为每次调度的开销被实际工作时间摊薄
- 设计决策:选择 pthreads 而非纤程库(保持极简),并发原语放在标准库而非语言层面(避免隐藏内存分配)
💡 金句
Go 的并发魔法来自用户态调度器。当你只能用内核线程时,让每个任务足够大,调度开销就会消失在信号中。
← 返回 Lobsters 首页