Go 并发机制一文通:goroutine、channel、同步/异步与典型场景

标题 Go 并发机制一文通:goroutine、channel、同步/异步与典型场景 副标题 / 摘要 这篇文章把 goroutine、channel、WaitGroup、mutex、context 讲清楚,并用工程场景说明它们如何组合使用,解决“同步/异步”和“队列/执行单元”的常见误解。 目标读者 初学者:刚接触 Go 并发,容易把 goroutine 当成队列。 中级开发者:需要在业务中稳定地使用 worker pool / fan-out / pipeline。 团队负责人:希望形成可执行的并发使用规范。 背景 / 动机 很多 Go 新手会把 goroutine 当成“队列”或“异步”的代名词,导致并发设计混乱: goroutine 是执行单元,而队列是数据结构;同步/异步是调用方式,与 goroutine 本身无关。 如果不厘清这些概念,就很容易出现 goroutine 泄漏、死锁、资源失控。 核心概念 goroutine:轻量级执行单元,类似线程,但调度由 Go runtime 负责。 channel:通信与同步原语,可无缓冲(同步握手)或有缓冲(队列语义)。 WaitGroup:等待一组 goroutine 完成。 mutex/RWMutex:共享内存的互斥访问控制。 context:取消、超时与跨 goroutine 传递控制信号。 同步/异步:是否等待结果返回的调用语义,而不是某个工具本身。 小结表格(快速定位概念边界): 概念 角色定位 典型用途 易错点 goroutine 执行单元 并发执行任务 泄漏/过量创建 channel 通信/同步 任务队列、流水线 未关闭、阻塞 WaitGroup 汇聚等待 fan-in/收口 Add/Done 不匹配 mutex 共享状态保护 map/缓存 死锁、长时间持锁 context 生命周期控制 超时/取消 没有传递或未检查 A — Algorithm(题目与算法) 主题用通俗话说: Go 并发 = “goroutine 负责跑、channel 负责传、WaitGroup 负责等、context 负责停”。 同步/异步只是“要不要等结果”,并不等于“有没有 goroutine”。 ...

2026年1月24日 · 4 分钟 · map[name:Jeanphilo]

Go 死锁入门:常见场景、排查方法与工程实践

标题 Go 死锁入门:常见场景、排查方法与工程实践 副标题 / 摘要 从 Go 运行时的 deadlock 报错切入,系统讲清死锁的本质、 最常见的触发方式,以及如何在工程中稳定规避。 目标读者 初学者:第一次写 Go 并发代码,对 deadlock 报错感到困惑。 中级开发者:需要建立稳定的并发协作流程,减少线上卡死。 团队负责人:想沉淀一套可执行的并发规范和排查手册。 背景 / 动机 在 Go 里,“死锁(deadlock)”指的是:所有 goroutine 都在等待某个事件发生 (通常是等锁、等 channel、等 WaitGroup),但这个事件永远不会发生。 典型报错是: fatal error: all goroutines are asleep - deadlock! 一旦触发,程序会卡住或直接退出,线上影响极大。 理解死锁的触发机制与排查路径,是 Go 并发开发的必修课。 核心概念 阻塞(Blocking):goroutine 等待 channel、锁或 WaitGroup,无法继续执行。 无缓冲 channel:发送/接收必须同时发生,否则阻塞。 WaitGroup 计数匹配:Add 的次数必须被 Done 抵消。 Mutex 不可重入:同一 goroutine 里重复 Lock 会自我阻塞。 锁顺序一致:多把锁必须统一获取顺序,避免交叉等待。 常见出现背景(什么时候容易发生) 生产者/消费者启动顺序错位:发送先发生、接收未就绪,常见于任务队列、worker pool。 扇出/扇入未配对:启动了多个 worker,但聚合端没把结果全部读完。 pipeline 未关闭或退出信号缺失:上游结束但下游仍 range 等待。 持锁做阻塞操作:拿着锁去收/发 channel、网络 I/O、或等待另一个锁。 多锁资源交叉持有:两个 goroutine 以不同顺序拿锁,形成循环等待。 为什么会出现(根因归纳) 等待关系闭环:A 等 B,B 等 C,C 等 A,没有外力打破。 同步原语用法不成对:channel 收发未配对、WaitGroup 计数未归零。 协程生命周期不一致:生产者先退出/未 close,消费者无限等。 锁粒度/顺序不清晰:共享资源越多,锁顺序越容易失控。 A — Algorithm(题目与算法) Go 运行时判定死锁的核心逻辑是: 当主 goroutine 在等待,且所有其他 goroutine 也都在等待,并且没有任何事件能 推动程序继续执行,runtime 会直接报错并终止。 ...

2026年1月19日 · 4 分钟 · map[name:Jeanphilo]