sync.waitgroup的基本用法
waitgroup类似于C中的信号灯,也可以理解成队列,基本的操作包括
add(int) 增加信号的值,add的参数应该都为正数
done() 减少信号的值,相当于add(-1)
wait() 等待信号值为0,等待期间会一直阻塞
waitgroup与channel产生的死锁
当同时使用了waitgroup和channel的话,要特别注意waitgroup.wait与读写chan的位置
例如下面的例子中在子线程中是先写入channel再减少信号的值,但是在主线程中是先等待信号值为0,再读channel的值,这样就引发了死锁
package main
import (
"log"
"sync"
)
func main() {
var wg sync.WaitGroup
ch := make(chan int)
for i := 0; i < 5; i++ {
wg.Add(1)
go func(i int) {
ch<-i
wg.Done()
}(i)
}
wg.Wait()
for i :=0; i<5; i++ {
v:=<-ch
log.Println(v)
}
log.Println("exit")
}
正确的写法应该是将waitgroup.wait放在读channel的后面
package main
import (
"log"
"sync"
)
func main() {
var wg sync.WaitGroup
ch := make(chan int)
for i := 0; i < 5; i++ {
wg.Add(1)
go func(i int) {
ch<-i
wg.Done()
}(i)
}
for i :=0; i<5; i++ {
v:=<-ch
log.Println(v)
}
wg.Wait()
log.Println("exit")
}
搞不懂GO中主线程和子线程间的内存是什么关系,看上面的现象应该是共享同一个内存空间的。