标准答案
- Mutex 临界区应短小,锁的获取顺序要稳定,释放放在 defer 中。
- RWMutex 允许并发读但写会阻塞读写,高竞争或临界区复杂时不一定优于 Mutex。
- Once 适合懒初始化,但初始化失败后的重试语义需要另行设计。
- WaitGroup 只等待计数归零,不传播任务错误、取消或结果,复杂任务可用 errgroup。
题目解析
Mutex 保护互斥临界区,RWMutex 只有在读多写少且读操作确实可并行时才有优势,Once 只保证初始化函数至多执行一次,WaitGroup 只负责等待计数归零。
WaitGroup 不传播错误、取消或结果,复杂任务应使用 errgroup 或明确结果 channel。RWMutex 也要求所有访问路径遵守同一锁边界,否则数据仍会竞争。
锁内工作要短小,释放放在 defer 中;多个锁要统一顺序。初始化失败后的 Once 语义和部分任务失败的业务策略需要额外设计。
常见误区
- 误区:在 goroutine 内 Add 导致 Wait 竞态。改正:启动 goroutine 前完成 Add,或使用更高层任务组。
- 误区:WaitGroup 只等待却丢失错误。改正:使用 errgroup/结果收集并传播错误和取消。
- 误区:读写锁保护的状态仍被无锁修改。改正:所有读写路径遵守同一同步协议。