锁是一种并发编程中的同步原语(Synchronization Primitives),它能保证多个goroutine在访问同一片内存时不会出现竞争条件(Race condition)等问题。

互斥锁 Mutex

读写互斥锁 RWMutex

是粒度更细的互斥锁,它不限制资源的并发读,但是读写、写写操作无法并行执行。能够在读操作远远多于写操作时提升性能。

WaitGroup

可以等待一组goroutine的返回,一个比较常见的使用场景是批量发出RPC或者HTTP请求

  1. requests := []*Request{...}
  2. wg := &sync.WaitGroup{}
  3. wg.Add(len(requests))
  4. for _, request := range requests {
  5. go func(r *Request) {
  6. defer wg.Done()
  7. // res, err := service.call(r)
  8. }(request)
  9. }
  10. wg.Wait()

Once

sync.Once可以保证在Go程序运行期间的某段代码只会执行一次。

  1. func main() {
  2. o := &sync.Once{}
  3. for i := 0; i < 10; i++ {
  4. o.Do(func() {
  5. fmt.Println("only once")
  6. })
  7. }
  8. }
  9. $ go run main.go
  10. only once

参考

同步原语与锁