Go的sync包解析
2023年8月23日
sync.Mutex互斥锁- 结构
type Mutex struct { state int32 // 锁状态位。 第0位:是否锁住;第1位:是否有goroutine被唤醒;剩余位:等待锁的 goroutine 数量 sema uint32 // 信号量,用于阻塞和唤醒 goroutine }- 方法
Lock()加锁。若已被锁住,则阻塞。UnLock()解锁。TryLock() bool尝试加锁。已被锁住,则返回false
sync.RWMutex读写锁- 结构
type RWMutex struct { w Mutex // 嵌入互斥锁。锁定期间 读、写 等待。 writerSem uint32 // semaphore for writers to wait for completing readers readerSem uint32 // readerCount atomic.Int32 // 当前读数量,负数表示有写等待或持有写锁 readerWait atomic.Int32 // 原子变量,写者等待时记录需要等待的读者数量,当这些读者释放后唤醒写者 }- 方法
Lock()加写锁。若已有读锁或写锁,则等待。UnLock()解写锁。TryLock() bool尝试加写锁。无锁返回true,已有读锁或写锁,则返回falseRLock()加读锁。若已有写锁,则等待。若有读锁,则读锁计数+1。RUnlock()解读锁,读锁计数-1TryRLock()尝试加读锁。无锁或有读锁返回true,已有写锁,则返回false
sync.Once确保函数只执行一次- 结构:互斥锁+原子标识
type Once struct { done atomic.Uint32 m Mutex }- 方法
Do(func())
sync.WaitGroup确保一组goroutine执行完成- 结构
type WaitGroup struct { noCopy noCopy // 禁止拷贝 state atomic.Uint64 // 高32位是计数器,低32位是等待者数量 sema uint32 // 信号量,用于阻塞和唤醒 goroutine }- 方法
Add(int)计数器+Done()计数器-1Wait()阻塞,直到计数器为0
sync.Cond条件变量- 结构
type Cond struct { noCopy noCopy // 禁止拷贝 L Locker // 用于加锁和解锁 notify notifyList // 等待者列表 checker copyChecker // 用于检测拷贝 }- 方法
Wait()阻塞,直到被唤醒Signal()唤醒一个等待者Broadcast()唤醒所有等待者NewCond(Locker)创建条件变量
sync.Pool对象池- 结构
type Pool struct { noCopy noCopy // 禁止拷贝 localSize uintptr // local 数组大小 victim unsafe.Pointer // victim 数组 victimSize uintptr // victim 数组大小 New func() any // 创建新对象的函数 }- 方法
Get() any获取对象Put(any)放入对象,注意放回时,每个属性都初始化掉。New(func() any)创建对象池
sync.Map并发安全的map- 结构
type Map struct { mu Mutex // 互斥锁 read atomic.Pointer[readOnly] // 只读的map dirty map[any]*entry // 脏的map misses int // 记录读miss的次数 }- 方法
Load(any) (any, bool)读取Store(any, any)写入LoadOrStore(any, any) (any, bool)读取或写入Delete(any)删除LoadAndDelete(any) (any, bool)读取并删除Range(func(key, value any) bool)遍历