sync¶
本文是 Go 标准库中 sync 包文档的翻译, 原文地址为: https://golang.org/pkg/sync/
概述¶
sync 包提供了诸如互斥锁这样的基本同步原语。 除了 Once 类型和 WaitGroup 类型之外, 包中的大多数其他类型都是为底层函数库程序准备的。 高层次的同步最好还是通过 channel 以及 communication 来完成。
包含本包定义的类型的值不应该进行拷贝。
Mutex 类型¶
一个 Mutex 就是一个互斥锁, 这种锁可以用作其他结构的一部分。
Mutex 的零值是一个未上锁的互斥锁 。
type Mutex struct {
// contains filtered or unexported fields
}
(*Mutex) Unlock 方法¶
func (m *Mutex) Unlock()
解锁 m 。 如果 m 并未加锁, 那么引发一个运行时错误。
被加锁的 Mutex 并不与特定的 goroutine 绑定, 在一个 goroutine 里面对 Mutex 进行加锁, 然后在另一个 goroutine 里面对 Mutex 进行解锁, 这是完全可行的。
WaitGroup 类型¶
一个 WaitGroup 会等待一系列 goroutine 直到它们全部运行完毕为止。 主 goroutine 通过调用 Add 方法来设置需要等待的 goroutine 数量, 而每个运行的 goroutine 则在它们运行完毕时调用 Done 方法。 与此同时, 调用 Wait 方法可以阻塞直到所有 goroutine 都运行完毕为止。
type WaitGroup struct {
// 其他已过滤或者未导出字段……
}
示例¶
这个示例会并发地获取给定的多个 URL , 并使用 WaitGroup 进行阻塞, 直到所有获取操作都已完成为止。
var wg sync.WaitGroup
var urls = []string{
"http://www.golang.org/",
"http://www.google.com/",
"http://www.somestupidname.com/",
}
for _, url := range urls {
// 对 WaitGroup 计数器执行加一操作
wg.Add(1)
// 启动一个 goroutine ,用于获取给定的 URL
go func(url string) {
// 在 goroutine 执行完毕时,对计数器执行减一操作
defer wg.Done()
// 获取 URL
http.Get(url)
}(url)
}
// 等待直到所有 HTTP 获取操作都执行完毕为止
wg.Wait()
(*WaitGroup) Add 方法¶
func (wg *WaitGroup) Add(delta int)
为 WaitGroup 计数器加上给定的增量 delta , 其中 delta 的值可以为负数。 当计数器的值变为 0 时, 所有被 Wait 阻塞的 goroutine 都将被释放。 当计数器的值变为负数时, Add 调用将引发一个 panic 。
当计数器的值为 0 时, delta 的值只能为正数, 并且对 Add 的调用必须出现在 Wait 调用之前; 当计数器的值大于 0 时, delta 的值既可以是正数也可以是负数, 并且对 Add 的调用可以发生在任何时候。 简单来说, 这意味着 Add 必须在创建 goroutine 的语句之前调用, 又或者在其他需要等待的事件之前调用。
在重复使用同一个 WaitGroup 对不同的独立事件集合(independent sets of events)进行等待时, 新的 Add 调用必须发生在之前的所有 Wait 调用均已返回的情况下。