Golang中的sync包是什么?如何使用?
在Go语言中,sync
包提供了基本的同步原语,如互斥锁(sync.Mutex
和sync.RWMutex
)和其他有用的同步类型,如sync.WaitGroup
,sync.Once
,和sync.Cond
。这些工具可以帮助你在多个goroutine之间进行同步操作,以避免竞态条件和数据不一致。
以下是一些基本使用示例:
1. 使用sync.Mutex
进行互斥锁定:
var (
counter int
mutex sync.Mutex
)
func increment() {
mutex.Lock()
defer mutex.Unlock()
counter++
}
func main() {
for i := 0; i < 1000; i++ {
go increment()
}
// wait for all goroutines to finish
time.Sleep(time.Second)
fmt.Println(counter) // Output: 1000
}
在上面的例子中,我们使用sync.Mutex
锁定对counter
的访问,以防止多个goroutine同时更新它。
2. 使用sync.WaitGroup
等待多个goroutine:
var wg sync.WaitGroup
func worker(id int) {
defer wg.Done()
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second)
fmt.Printf("Worker %d done\n", id)
}
func main() {
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker(i)
}
wg.Wait()
fmt.Println("All workers done")
}
在这个例子中,我们使用sync.WaitGroup
来等待所有的工作goroutine完成。
3. 使用sync.Once
保证只执行一次:
var once sync.Once
func setup() {
fmt.Println("Setup done")
}
func doSetup() {
once.Do(setup)
}
func main() {
go doSetup()
go doSetup()
// wait for one of the setup calls to finish
time.Sleep(time.Second)
}
在这个例子中,我们使用sync.Once
确保setup
函数只被执行一次,即使在并发环境下。