Overview

sync提供了同步原语比如互斥锁,以及Once,WaitGroup类型.大多都供底层例层使用,高级同步更好地的使用通过通道和交流,该包包含的值不应该被复制

type Cond


type Cond struct {
    // L 被用来观察和改变条件
    L Locker
    // contains filtered or unexported fields
}

Cond实现了条件变量,多个goroutines的汇合点或者宣布事件的发生.每个Cond都有关联的Locker(通常是*Mutex或者*RWMutex),可以改变条件变量或者可以调用Wait方法,在第一次使用之后,不应该被复制

func NewCond(l Locker) *Cond

NewCond通过l返回一个新的Cond

func (c *Cond) Broadcast()

Broadcast唤醒所有等待c的通道 允许但不要求调用者持有c.L

func (c *Cond) Signal()

如果有的话,c唤醒等待c的一个goroutine 允许但不要求调用者持有c.L

func (c *Cond) Wait()

Wait自动解锁c.L并且暂停当前goroutine的执行,之后恢复执行,Wait在返回前锁住c.L,不像其他系统,Wait不能返回除非被Signal或Broadcast唤醒 因为c.L不是被锁的在Wait第一次被唤醒之前,调用者通常不能确保条件是true当Wait返回.而不是,调用者应该在循环中等待.
c.Locker.Lock()
if !condition() {
    c.Wait()
}
... make use of condition ...
c.L.Lock()

type Locker


type Locker interface {
    Lock()
    Unlock()
}

Locker表示一个可以被锁和解锁的对象

type Map


type Map struct {
    // contains filtered or unexported fields
}
Map和map[interface{}]interface{},但是对于多个goroutine并发是安全的,而不用增加锁和协调,Loads,stores,deletes,分摊常数时间 Map是特化的,大多数时候应该使用带锁和协调的map,以更好的类型安全和更简单的维护map中不变的内容 Map对于两种用例进行了优化:

对于给定的key入口只写入一次但是读取多次,当作只增的缓存

当多个goroutine读取,写入,覆写不相交的入口key

在这两种情况下,使用Map能够明显的减少锁竞争,对于map使用分开的Mutex或RWMutex Map的零值是空的并准备使用,当第一次使用后必须不能被使用.

func (m *Map) Delete(key interface{})

Delete删除给定的key的值

func (m *Map) Load(key interface{}) (value interface{}, ok bool)

Load返回存储在m给定key的值,或者value不存在返回nil,ok表明是否在map中找到value

func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)

LoadOrStore返回对于key存在的值,否则,进行储存和返回给定的value,loaded返回ture,如果值是被加载的,返回false,如果值是被存储的

func (m *Map) Range(f func(key, value interface{}) bool)

Range对于Map连续的key和value调用f,如果f返回true,Range停止迭代 Range对于Map内容任何一致的快照不是必须的:对于map中key访问不会超过一次,但是如果同时储存和删除,Range可能反射任何key在Range调用期间 Range可能O(N)时间复杂度,即使Range在常数个元素返回false

func (m *Map) Store(key, value interface{})

Store给给定key为value

type Mutex


type Mutex struct {
    // contains filtered or unexported fields
}
Mutex是一个互斥锁,Mutex的零值是一个不被锁的互斥量 Mutex第一次使用后不能被复制

func (m *Mutex) Lock()

Lock会锁住m,如果锁已经被锁,当前goroutine将会被阻塞直到mutex可用

func (m *Mutex) Unlock()

Unlock解锁m,如果m没有被锁而Unlock,会发生runtime-error 一个锁住的mutex并不是和一个特别的goroutine关联的,允许一个goroutine锁住mutex,而安排其他goroutine去Unlock

type Once


type Once struct {
    // contains filtered or unexported fields
}

Once是一个只会执行一次动作的对象

func (o *Once) Do(f func())

Do调用函数f只有当Once实例第一次调用Do,换句话说,给定:
var once Once

如果once.Do(f)调用多次,只有第一次触发,即使f拥有不同的value每次调用,每次函数执行都要求Once的新实例,Do用于初始化被精确的执行一次,如果f产生panic,以后调用f将会直接返回

type Pool


type Pool struct {
    // New可选的指定一个函数产生一个值当Get,否则返回nil
    // 并发调用Get .,可能不会发生改变
    New func() interface{}
    // contains filtered or unexported fields
}

Pool是一个可能被单独地保存和取出的临时对象的集合,任何存储在Pool里的元素可能会无通知的被删除,当发生时,如果Pool只拥有引用,元素可能会被重新分配 Pool能够被多个goroutine安全地同时使用 Pool的目的缓存已分配的元素,而不是之后使用的未使用元素,减轻垃圾收集器的负担,Pool很简单的构建线程安全的空闲列表,但是不适合所有空闲列表. 一个合适的使用Pool场景是管理一组临时元素,默默的分享和潜在地被包中其他客户并发使用,Pool提供一个方法去缓冲使用在多个客户之上, Pool好的使用例子在负责分配动态大小临时缓冲区的fmt package 另一方面,一个空闲列表负责维护短暂生命期的对象不适合使用Pool Pool在第一次使用后不应该不复制

func (p *Pool) Get() interface{}

Get从Pool任意挑选一个对象,从Pool删除并返回给调用者,Get可能会忽视pool,并将其视为nil,调用者不应该对Get和Put的值关系和任何假设,如果Get乐意而不是返回nil且p.New非nil,Get返回p.New的结果

func (p *Pool) Put(x interface{})

Put添加x到pool

type RWMutex


type RWMutex struct {
    // contains filtered or unexported fields
}

RWMutex是读写互斥锁,该锁能够被任意个读者或者一个写者拥有,RWMutex的零值是未锁的互斥量 RWMutex第一次使用后不能被复制 如果一个goroutine持有RWMutex的读,另一个goroutine可能调用Lock,没有goroutine应该期待能够获得读锁直到最初的读锁被释放,特别地,这个禁止递归读锁.这确保锁最终可用,Lock将会阻塞除了一个新的读者获得锁

func (rw *RWMutex) Lock()

Lock锁住锁的写端,如果对于写端和读端,锁早已锁定,Lock会阻塞直到可用

func (rw *RWMutex) RLock()

RLock锁住读端,不应该被用于递归读取,Lock调用将会阻塞,除了一个新的读者获得锁

func (rw *RWMutex) RLocker() Locker

RLocker获得读端的Locker接口,可以调用Lock和Unlock

func (rw *RWMutex) RUnlock()

RUnlock撤销一个RLock调用,对于其他同时的读者不产生影响,如果rw读端没有被锁,将会造成runtime-error

func (rw *RWMutex) Unlock()

Unlock将会解锁写端,如果写端没有被锁,将会产生runtime-error,和Mutex类似,RWMutex并不和一个指定的goroutine关联,可以在一个gorotine执行RLock(Lock),其他goroutine执行RUnlock(Unlock).

type WaitGroup


type WaitGroup struct {
    // contains filtered or unexported fields
}

WaitGroup等待一个集合的goroutine完成,main goroutine设置Add的gorouine数量,每个gorountine完成调用Done,与此同时,Wait能够阻塞直到所有gorutine完成

func (wg *WaitGroup) Add(delta int)

Add增加差分,差分可能是负值,到WaitGroup计数器,如果计数器是零,Wait的所有goroutine都被释放,如果计数器变成负值,Add会panic. 注意当计数器为0时,增加一个正的delta应该在调用Wait之前

func (wg *WaitGroup) Done()

将计时器减1

func (wg *WaitGroup) Wait()

Wait阻塞直到计时器为0