Go 并发原语
Go 并发原语Go 语言提供了丰富的并发原语同步工具涵盖锁、原子操作、通道、等待组、一次性执行等类别一、 分类类别包含原语目标互斥同步Mutex、RWMutex保护临界区保证独占 / 读写安全原子操作atomic无锁操作单个变量极致性能同步协调WaitGroup、Cond、Once协调 goroutine 执行顺序 / 时机通信共享channel无缓冲 / 有缓冲goroutine 间通信二、对比2.1 互斥锁Mutex 和 RWMutex特性MutexRWMutex加锁规则同一时间仅一个 goroutine 加锁读锁多 goroutine 并发写锁仅一个 goroutine互斥关系读写 / 写写 / 读读均互斥读写 / 写写互斥读读不互斥性能简单无额外开销读多写少场景性能更高有状态管理开销缺点读并发性能差写锁阻塞所有读锁状态管理有开销适用场景读写频率相当、写操作占比高读多写少如配置读取、缓存查询2.2 原子操作sync/atomicvs Mutex特性sync/atomicMutex操作粒度单个变量int32/64、uintptr、Pointer 等任意临界区变量 / 代码块 / 数据结构实现方式CPU 原子指令无锁自旋 阻塞 信号量有锁性能极致快约 1ns / 次无竞争约 10ns / 次有竞争大幅下降功能限制仅支持原子读写 / 增减 / 交换支持任意逻辑如复合操作、数据结构修改适用场景简单变量的并发读写计数器、标志位复杂临界区、复合操作风险易误用如非原子操作组合死锁、锁粒度大导致性能差2.3 Channel vs Mutex通信 vs 共享内存特性channel通道Mutex设计理念通信共享内存Go 推荐共享内存加锁同步方式阻塞式通信发送 / 接收阻塞阻塞式加锁适用场景goroutine 间数据传递、任务分发、限流保护共享资源的读写优点逻辑清晰、天然避免死锁无锁简单直接、适配所有临界区缺点有内存开销通道缓冲区、性能略低易死锁、需手动管理锁配对性能无竞争发送 / 接收约 20ns / 次加解锁约 10ns / 次典型用法生产者 - 消费者、goroutine 池、信号通知共享变量 / 数据结构保护2.4 同步协调原语WaitGroup vs Once vs Cond特性sync.WaitGroupsync.Oncesync.Cond核心功能等待一组goroutine完成保证函数仅执行一次条件变量唤醒等待的goroutine触发方式Add()Done()Wait()Do(func())Wait()Signal()/Broadcast()适用场景批量 goroutine 等待如多任务执行单例初始化、配置加载多 goroutine 等待某个条件满足优点轻量、易用线程安全、无需手动加锁精准控制唤醒单个 / 全部缺点不可重用计数归 0 后不可再用仅支持单次执行需配合 Mutex 使用逻辑复杂典型用法等待 10 个 goroutine 完成任务初始化数据库连接仅一次等待队列非空后唤醒消费者