package sync

import "sync"

sync包提供了基本的同步基元,如互斥锁。除了Once和WaitGroup类型,大部分都是适用于低水平程序线程,高水平的同步使用channel通信更好一些。

本包的类型的值不应被拷贝。

Index

type Locker
type Once
func (o *Once) Do(f func())
type Mutex
func (m *Mutex) Lock()
func (m *Mutex) Unlock()
type RWMutex
func (rw *RWMutex) Lock()
func (rw *RWMutex) Unlock()
func (rw *RWMutex) RLock()
func (rw *RWMutex) RUnlock()
func (rw *RWMutex) RLocker() Locker
type Cond
func NewCond(l Locker) *Cond
func (c *Cond) Broadcast()
func (c *Cond) Signal()
func (c *Cond) Wait()
type WaitGroup
func (wg *WaitGroup) Add(delta int)
func (wg *WaitGroup) Done()
func (wg *WaitGroup) Wait()
type Pool
func (p *Pool) Get() interface{}
func (p *Pool) Put(x interface{})

Examples

返回首页

  • Once
  • WaitGroup

type Locker

type Locker interface {    Lock()    Unlock()
}

Locker接口代表一个可以加锁和解锁的对象。

type Once

type Once struct {    // 包含隐藏或非导出字段}

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

Example

func (*Once) Do

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

Do方法当且仅当第一次被调用时才执行函数f。换句话说,给定变量:

var once Once

如果once.Do(f)被多次调用,只有第一次调用会执行f,即使f每次调用Do 提供的f值不同。需要给每个要执行仅一次的函数都建立一个Once类型的实例。

Do用于必须刚好运行一次的初始化。因为f是没有参数的,因此可能需要使用闭包来提供给Do方法调用:

config.once.Do(func() { config.init(filename) })

因为只有f返回后Do方法才会返回,f若引起了Do的调用,会导致死锁。

type Mutex

type Mutex struct {    // 包含隐藏或非导出字段}

Mutex是一个互斥锁,可以创建为其他结构体的字段;零值为解锁状态。Mutex类型的锁和线程无关,可以由不同的线程加锁和解锁。

func (*Mutex) Lock

func (m *Mutex) Lock()

Lock方法锁住m,如果m已经加锁,则阻塞直到m解锁。

func (*Mutex) Unlock

func (m *Mutex) Unlock()

Unlock方法解锁m,如果m未加锁会导致运行时错误。锁和线程无关,可以由不同的线程加锁和解锁。

type RWMutex

type RWMutex struct {    // 包含隐藏或非导出字段}

RWMutex是读写互斥锁。该锁可以被同时多个读取者持有或唯一个写入者持有。RWMutex可以创建为其他结构体的字段;零值为解锁状态。RWMutex类型的锁也和线程无关,可以由不同的线程加读取锁/写入和解读取锁/写入锁。

func (*RWMutex) Lock

func (rw *RWMutex) Lock()

Lock方法将rw锁定为写入状态,禁止其他线程读取或者写入。

func (*RWMutex) Unlock

func (rw *RWMutex) Unlock()

Unlock方法解除rw的写入锁状态,如果m未加写入锁会导致运行时错误。

func (*RWMutex) RLock

func (rw *RWMutex) RLock()

RLock方法将rw锁定为读取状态,禁止其他线程写入,但不禁止读取。

func (*RWMutex) RUnlock

func (rw *RWMutex) RUnlock()

Runlock方法解除rw的读取锁状态,如果m未加读取锁会导致运行时错误。

func (*RWMutex) RLocker

func (rw *RWMutex) RLocker() Locker

Rlocker方法返回一个互斥锁,通过调用rw.Rlock和rw.Runlock实现了Locker接口。

type Cond

type Cond struct {    // 在观测或更改条件时L会冻结
    L Locker
    // 包含隐藏或非导出字段}

Cond实现了一个条件变量,一个线程集合地,供线程等待或者宣布某事件的发生。

每个Cond实例都有一个相关的锁(一般是*Mutex或*RWMutex类型的值),它必须在改变条件时或者调用Wait方法时保持锁定。Cond可以创建为其他结构体的字段,Cond在开始使用后不能被拷贝。

func NewCond

func NewCond(l Locker) *Cond

使用锁l创建一个*Cond。

func (*Cond) Broadcast

func (c *Cond) Broadcast()

Broadcast唤醒所有等待c的线程。调用者在调用本方法时,建议(但并非必须)保持c.L的锁定。

func (*Cond) Signal

func (c *Cond) Signal()

Signal唤醒等待c的一个线程(如果存在)。调用者在调用本方法时,建议(但并非必须)保持c.L的锁定。

func (*Cond) Wait

func (c *Cond) Wait()

Wait自行解锁c.L并阻塞当前线程,在之后线程恢复执行时,Wait方法会在返回前锁定c.L。和其他系统不同,Wait除非被Broadcast或者Signal唤醒,不会主动返回。

因为线程中Wait方法是第一个恢复执行的,而此时c.L未加锁。调用者不应假设Wait恢复时条件已满足,相反,调用者应在循环中等待:

c.L.Lock()
for !condition() {
    c.Wait()
}
... make use of condition ...
c.L.Unlock()

type WaitGroup

type WaitGroup struct {    // 包含隐藏或非导出字段}

WaitGroup用于等待一组线程的结束。父线程调用Add方法来设定应等待的线程的数量。每个被等待的线程在结束时应调用Done方法。同时,主线程里可以调用Wait方法阻塞至所有线程结束。

Example

func (*WaitGroup) Add

func (wg *WaitGroup) Add(delta int)

Add方法向内部计数加上delta,delta可以是负数;如果内部计数器变为0,Wait方法阻塞等待的所有线程都会释放,如果计数器小于0,方法panic。注意Add加上正数的调用应在Wait之前,否则Wait可能只会等待很少的线程。一般来说本方法应在创建新的线程或者其他应等待的事件之前调用。

func (*WaitGroup) Done

func (wg *WaitGroup) Done()

Done方法减少WaitGroup计数器的值,应在线程的最后执行。

func (*WaitGroup) Wait

func (wg *WaitGroup) Wait()

Wait方法阻塞直到WaitGroup计数器减为0。

type Pool

type Pool struct {    // 可选参数New指定一个函数在Get方法可能返回nil时来生成一个值
    // 该参数不能在调用Get方法时被修改
    New func() interface{}    // 包含隐藏或非导出字段}

Pool是一个可以分别存取的临时对象的集合。

Pool中保存的任何item都可能随时不做通告的释放掉。如果Pool持有该对象的唯一引用,这个item就可能被回收。

Pool可以安全的被多个线程同时使用。

Pool的目的是缓存申请但未使用的item用于之后的重用,以减轻GC的压力。也就是说,让创建高效而线程安全的空闲列表更容易。但Pool并不适用于所有空闲列表。

Pool的合理用法是用于管理一组静静的被多个独立并发线程共享并可能重用的临时item。Pool提供了让多个线程分摊内存申请消耗的方法。

Pool的一个好例子在fmt包里。该Pool维护一个动态大小的临时输出缓存仓库。该仓库会在过载(许多线程活跃的打印时)增大,在沉寂时缩小。

另一方面,管理着短寿命对象的空闲列表不适合使用Pool,因为这种情况下内存申请消耗不能很好的分配。这时应该由这些对象自己实现空闲列表。

func (*Pool) Get

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

Get方法从池中选择任意一个item,删除其在池中的引用计数,并提供给调用者。Get方法也可能选择无视内存池,将其当作空的。调用者不应认为Get的返回这和传递给Put的值之间有任何关系。

假使Get方法没有取得item:如p.New非nil,Get返回调用p.New的结果;否则返回nil。

func (*Pool) Put

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

Put方法将x放入池中。

本文分享自微信公众号 - Golang语言社区(Golangweb)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-05-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • go语言的匿名函数

    1-声明一个匿名函数 func(参数列表) 返回值列表 { 函数体… } 2-匿名函数的调用

    李海彬
  • package runtime

    runtime包提供和go运行时环境的互操作,如控制go程的函数。它也包括用于reflect包的低层次类型信息;参见reflect报的文档获取运行时类型系统的可...

    李海彬
  • package debug

    Package debug contains facilities for programs to debug themselves while they ar...

    李海彬
  • 小朋友学Python(27):全局变量的引用和修改

    一、引用 例1 a = 1 def func(): if 1 == a: print("a = %d" % a) if __name__...

    海天一树
  • 73-递归函数计算阶乘

    凯茜的老爸
  • go语言的匿名函数

    1-声明一个匿名函数 func(参数列表) 返回值列表 { 函数体… } 2-匿名函数的调用

    李海彬
  • Python笔记:装饰器(面向切面)

    http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html

    超级大猪
  • JavaScript依赖注入的实现思路

    JavaScript依赖注入的实现思路 如今各个框架都在模块化,连前端的javascript也不例外。每个模块负责一定的功能,模块与模块之间又有相互依赖,那么问...

    用户1289394
  • package runtime

    runtime包提供和go运行时环境的互操作,如控制go程的函数。它也包括用于reflect包的低层次类型信息;参见reflect报的文档获取运行时类型系统的可...

    李海彬
  • 在Python中将函数作为另一个函数的参数传入并调用的方法

    在旧版本中,可以使用apply(function, *args, **kwargs)进行调用,但是在新版本中已经移除,以function(*args, **kw...

    于小勇

扫码关注云+社区

领取腾讯云代金券