go sync包的相关使用

了解go sync包互斥锁Mutex,读写锁RWMutex,WaitGroup的使用

Locker 接口

    整个sync包都围绕这Locker进行,这是一个interface:
    type Locker interface {
            Lock()
            Unlock()
    }

Mutex互斥锁

    type Mutex struct{
           // something
    }
    func (m *Mutex) Lock()
    func (m *Mutex) Unlock()

Mutex 的零值是一个未上锁的互斥锁。被加锁的Mutex并不与特定的goroutine绑定,在一个goroutine里面对 Mutex 进行加锁,然后在另一个goroutine里面对 Mutex 进行解锁, 这是完全可行的。

  • 在一个 goroutine 获得 Mutex 后,其他 goroutine 只能等到这个 goroutine 释放该 Mutex
  • 使用 Lock() 加锁后,不能再继续对其加锁,直到利用 Unlock() 解锁后才能再加锁
  • 在 Lock() 之前使用 Unlock() 会导致 panic 异常
  • 已经锁定的 Mutex 并不与特定的 goroutine 相关联,这样可以利用一个 goroutine 对其加锁,再利用其他 goroutine 对其解锁
  • 在同一个 goroutine 中的 Mutex 解锁之前再次进行加锁,会导致死锁
  • 适用于读写不确定,并且只有一个读或者写的场景

RWMutex读写锁

    type RWMutex struct{
           // something
    }
    func (m *RWMutex) Lock()  // 加写锁
    func (m *RWMutex) Unlock() // 解写锁
    func (m *RWMutex) RLock()  // 加读锁
    func (m *RWMutex) RUnlock() // 解读锁
  • RWMutex是单写多读锁,该锁可以加多个读锁或者一个写锁
  • 读锁占用的情况下会阻止写,不会阻止读,多个goroutine可以同时获取读锁
  • 写锁会阻止其他 goroutine(无论读和写)进来,整个锁由该goroutine独占
  • 适用于读多写少的场景

WaitGroup

    type WaitGroup struct{
           // something
    }
    func (wg *WaitGroup) Add(delta int)     // 新增标记当前执行线程数+1
    func (wg *WaitGroup) Done()             // 标记当前执行线程数-1
    func (wg *WaitGroup) Wait()             // 等待所有线程结束任务
  • WaitGroup对象不是一个引用类型,在通过函数传值的时候需要使用地址,即wg *WaitGroup通过指针传值。

扩展1-Cond条件变量

    type Cond struct {
        noCopy noCopy
        // L is held while observing or changing the condition
        L Locker
        notify  notifyList
        checker copyChecker
    }
    func NewCond(l Locker) *Cond        //
    func (c *Cond) Broadcast()          //广播通知
    func (c *Cond) Signal()             //单发通知
    func (c *Cond) Wait()               //等待通知

扩展2-sync.Pool临时对象池

    type Pool struct {
        noCopy noCopy
    
        local     unsafe.Pointer // local fixed-size per-P pool, actual type is [P]poolLocal
        localSize uintptr        // size of the local array
    
        // New optionally specifies a function to generate
        // a value when Get would otherwise return nil.
        // It may not be changed concurrently with calls to Get.
        New func() interface{}                  // 提供new方法,当pool为空时默认新建对象                   
    }
    
    func (p *Pool) Get() interface{}            //获取对象
    func (p *Pool) Put(x interface{})           //存入对象

扩展3-sync.Once

type Once struct {
    m    Mutex
    done uint32
}
func (o *Once) Do(f func())

顾名思义,保证函数只执行一此

总结

go sync提供的多种锁功能齐全。get it!!!

Life is more than the present.