Golang学习笔记-sync包

本文介绍了Go语言中的sync包,包括Cond、Locker接口、Map、Mutex、Once、Pool、RWMutex和WaitGroup的使用。Cond用于条件变量,支持等待和唤醒操作。Map是协程安全的,适合并发环境。Mutex和RWMutex提供互斥锁和读写锁。Once确保操作只执行一次。Pool管理临时对象。WaitGroup用于等待一组goroutine完成。各种数据结构和工具在并发编程中扮演重要角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • sync包使用

    Cond:实现了条件变量,用于等待gorouting或者声明事件的发生。Cond在第一次使用后不可以被拷贝
    Locker:一个接口,包含Lock()和Unlock()两个方法,用于代表一个能被加锁和解锁的对象。
    Map:一个协程安全的map,map[interface{}]interface{},key和value均可以是任意类型。
    Mutex:互斥锁
    Once:当某个action仅希望被执行1次时使用sync.Once
    Pool:临时对象池
    RWMutex:读写互斥锁
    WaitGroup:用于等待一组gorouting完成

    Cond

    Cond包含如下几个方法:

    • NewCond(l Locker) *Cond
      用于创建一个Cond对象,需要传入实现了Locker接口的对象,比如Mutex
    • func(c *Cond) Broadcast()
      用于唤醒全部等待Cond条件的gorouting
    • func(c *Cond) Signal()
      用于唤醒一个等待Cond条件的gorouting
    • func(c *Cond) Wait()
      等待通知,gorouting阻塞等待

    Locker

    一个interface,声明了Lock()、Unlock()两个接口

    Map

    Map 类型是专门的。大多数代码应该使用带有单独锁定或协调的普通 Go 映射,以获得更好的类型安全性并更容易维护其他不变量以及映射内容。

    Map的使用场景

    • 当给定键的条目只写入一次但读取多次时,如在只会增长的缓存中
    • 当多个 goroutine 读取、写入和覆盖不相交的键集的条目。
      在这两种情况下,与使用单独的 Mutex 或 RWMutex 配对的 Go map 相比,使用 Map 可以显着减少锁争用。

    Map的使用方法

    • func (m *Map) Delete(key interface{})
      删除一个key对应的value
    • func (m *Map) Load(key interface{}) (value interface{}, ok bool)
      返回保存的key对应的value,如果不存在,value返回nil,ok表示key是否存在
    • func (m *Map) LoadAndDelete(key interface{}) (value interface{}, loaded bool)
      删除Key对应的value,同时返回之前保存的value,loaded表示是否key是否存在。
    • func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)
      返回key在map中已经存在的value,如果value不存在,则将入参的value保存的Map中。loaded返回key是否存在
    • func (m *Map) Range(f func(key, value interface{}) bool)
      遍历每一个key并调用f,如果f返回false则遍历终止。
    • func (m *Map) Store(key, value interface{})
      存储key和value,如果key已存在则覆盖

    Mutex

    互斥锁,支持Lock()、Unlock()两种方法.Mutux不能被拷贝

    • func (m *Mutex) Lock()
      锁定mutex,如果mutex已经被锁定则gorouting会被阻塞
    • func (m *Mutex) Unlock()
      解锁mutex,如果mutex未被锁定会引起运行时错误。

    Once

    一个只执行一次动作的结构体,不可以被拷贝

    • func (o *Once) Do(f func())
      调用f方法,并且保证只有第一次才会调用。用于初始化那些必须只能被执行一次的动作。

    Pool

    用于存放一组可以独立存储、获取的临时的对象的集合。
    池子中的元素可能会被自动移除并且得不到任何的通知。如果Pool 控制了对象的仅有的引用则可能被释放。
    协程安全

    • 初始化Pool时需要制定Pool中的New方法,用于指明如何新建池子中的对象
    • func (p *Pool) Get() interface{}
      返回池子中的任意数据并将该数据从池子中移除。如果p.New未空,则get不到就返回nil,否则返回New的结果
    • func (p *Pool) Put(x interface{})
      将x放回池子

    RWMutex

    读写互斥锁,第一次使用后不得复制,可以被单个作者或多个读者持有。RWMutex类型的锁也和线程无关,可以由不同的线程加读取锁/写入和解读取锁/写入锁。

    1. 可以加多个读锁或者一个写锁
    2. 写锁权限高于读锁,有写锁时优先进行写锁定
    3. 读锁占用的情况下会阻止写,不会阻止读,多个 goroutine 可以同时获取读锁
    4. 写锁会阻止其他 goroutine(无论读和写)进来,整个锁由该 goroutine 独占
    • func (rw *RWMutex) Lock()
      写锁定,如果锁已经被读或写锁定,则Lock方法将会阻塞
    • func (rw *RWMutex) RLock()
      读锁定,不能递归调用读锁定,阻塞的Lock调用将新的读者排除在获取锁之外。
    • func (rw *RWMutex) RLocker() Locker
      返回一个Locker接口,该接口通过调用rw.RLock和rw.RUnlock实现Lock和Unlock方法。
    • func (rw *RWMutex) RUnlock()
      撤销单个RLock调用;不会影响其他同时读的读者,如果调用RUnlock时无RLock则会panic
    • func (rw *RWMutex) Unlock()
      接入rw锁定,如果Unlock调用时没有Lock则会panic

    WaitGroup

    用于等待一组gorouting完成。启动gorouting的main gorouting通过Add设置需要等待的gorouting的数量,然后每个gorouting在完成时调用Done。main gorouting调用Wait阻塞等待直至所有gorouting完成
    第一次使用后不能被拷贝

    • func (wg *WaitGroup) Add(delta int)
      将WaitGroup的计数器增加delta,delta可以为负值。如果WaitGroup的计数器变为0则所有阻塞在Wait()的gorouting将会被释放,如果计数器变为负值则会panic
      Add应该在创建gourouting之前执行,如果重用WaitGroup,必须要等到之前所有Wait都返回后再重新Add。
    • func (wg *WaitGroup) Done()
      将WaitGroup计数器减1
    • func (wg *WaitGroup) Wait()
      阻塞等待直至WaitGroup计数器变为0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值