0%

Golang sync.WaitGroup 的用法

Golang sync.WaitGroup 的用法


介绍

1
2
3
4
5
6
func main(){
for i := 0; i < 100 ; i++{
go fmt.Println(i)
}
time.Sleep(time.Second)
}

主线程为了等待goroutine都运行完毕,不得不在程序的末尾使用time.Sleep() 来睡眠一段时间,等待其他线程充分运行。

对于实际生活的大多数场景来说,1秒是不够的,并且大部分时候我们都无法预知for循环内代码运行时间的长短。这时候就不能使用time.Sleep() 来完成等待操作了。

对于这种情况,go语言中有一个其他的工具sync.WaitGroup 能更加方便的帮助我们达到这个目的。

WaitGroup 对象内部有一个计数器,最初从0开始

有三个方法:Add(), Done(), Wait() 用来控制计数器的数量

  • Add(n) 把计数器新增n
  • Done() 每次把计数器-1
  • wait() 会阻塞代码的运行,直到计数器地值减为0。

注意事项

计数器不能为负值

不能使用Add() 给wg 设置一个负值,否则代码将会报错

同样使用Done() 也要特别注意不要把计数器设置成负数

WaitGroup对象不是一个引用类型

WaitGroup对象不是一个引用类型,在通过函数传值的时候需要使用地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func main() {
wg := sync.WaitGroup{}
wg.Add(100)
for i := 0; i < 100; i++ {
go f(i, &wg)
}
wg.Wait()
}

// 一定要通过指针传值,不然进程会进入死锁状态
func f(i int, wg *sync.WaitGroup) {
fmt.Println(i)
wg.Done()
}