Golang 之sync包应用
sync.Mutex
保证共享资源的互斥访问
mutex := &sync.Mutex{} mutex.Lock() // Update共享变量 (比如切片,结构体指针等) mutex.Unlock()
sync.RWMutex
读写互斥锁,可以对读加锁
mutex := &sync.RWMutex{} mutex.Lock() // Update 共享变量 mutex.Unlock() mutex.RLock() // Read 共享变量 mutex.RUnlock()
sync.WaitGroup
使用Add()添加计数,Done()减掉一个计数,计数不为0, 阻塞Wait()的运行
将数组每个值取平方,最后求所有的值的和,可以开数组大小的协程,用sync控制所有的协程都计算完成
package main import ( "fmt" "sync" ) func opera(a int, taskres chan int, wg *sync.WaitGroup) { taskres <- a * a wg.Done() } func main() { a := []int{3, 5, 4, 7, 3, 8, 1} taskres := make(chan int, len(a)) var wg sync.WaitGroup for _, v := range a { wg.Add(1) go opera(v, taskres, &wg) } wg.Wait() close(taskres) var result int = 0 //range只能for关闭了的channel for i := range taskres { result += i } fmt.Println(result) }
sync.Map
sync.Pool
sync.Once
保证一个函数仅被执行一次
once := &sync.Once{} for i := 0; i < 4; i++ { i := i go func() { once.Do(func() { fmt.Printf("first %d\n", i) }) }() }
sync.Cond
用于goroutine之间的协作,用于协程的挂起和唤醒。
避免轮训空等,待着就好,wait别人signal你
func main() { cond := sync.NewCond(new(sync.Mutex)) condition := 0 // Consumer go func() { for { cond.L.Lock() for condition == 0 { cond.Wait() } condition-- fmt.Printf("Consumer: %d\n", condition) cond.Signal() cond.L.Unlock() } }() // Producer for { time.Sleep(time.Second) cond.L.Lock() for condition == 3 { cond.Wait() } condition++ fmt.Printf("Producer: %d\n", condition) cond.Signal() cond.L.Unlock() } }
输出:
Producer: 1 Consumer: 0 Producer: 1 Consumer: 0 Producer: 1 Consumer: 0 Producer: 1 Consumer: 0 Producer: 1 Consumer: 0
本文来自博客园,作者:LeeJuly,转载请注明原文链接:https://www.cnblogs.com/peterleee/p/13406047.html