跳到主要内容

同步工具选择

为什么需要同步工具?​

  • 同步: 协调多个 goroutine 的执行顺序或共享数据访问,避免读到一半状态或互相覆盖写入;
  • 数据竞争入口: 定义与检测方式见并发设计,本篇只承担工具选择;
  • 选择起点: 先判断目标是“保护共享状态”“等待任务完成”还是“只初始化一次”,再选择工具;

如何根据问题选择工具?​

工具优先使用场景
sync/atomic简单计数器、状态标记的原子读写
sync.Mutex共享变量, map 或多项状态, 复合不变量的互斥访问
sync.RWMutex共享数据读多写少, 需要允许多个读取并发执行
sync.WaitGroup等待多个并发任务结束
sync.Once只执行一次的初始化
  • 选择示例: 并发请求各自累加次数可用 atomic;账户扣款与余额校验必须作为一个整体时用 Mutex;批量请求收尾用 WaitGroup;固定配置初始化用 Once;
保护一份共享状态? → 先考虑 Mutex
只是一个计数的增减?→ 可评估 atomic
只等所有任务结束? → WaitGroup
初始化必须最多一次?→ Once
需要交接数据或事件?→ channel

选择时容易犯什么错误?​

  • atomic 误用: 多个字段必须一起满足业务规则时,分别做原子读写不能保护整体不变量,应使用 Mutex;

  • RWMutex 误用: 读多写少只是候选条件;临界区很短或竞争很低时,普通 Mutex 往往更简单;

  • WaitGroup 边界: 只等待任务完成,不保护任务读写的共享数据;

  • Once 选择入口: 失败重试与资源刷新不适合 Once,具体执行及 panic 规则见Once;

  • channel 选择: 需要传递数据所有权或表达事件顺序时优先考虑 channel,不必把所有并发问题都改成共享内存加锁;

  • 组合边界: 等待与互斥是不同责任,同一批任务可以同时需要 WaitGroup 和 Mutex;加一个工具前先指出它保护的状态或建立的完成关系;