今天采用WaitGroup来实现协程,发现range chanel会死锁,代码如下:package main
import "sync"
import "fmt"
func main() {
var wg sync.WaitGroup
wg.Add(3)
resultChannel := make(chan int, 3)
routineFunc := func(i int) {
defer wg.Done()
resultChannel <- i
fmt.Println("push to channel,", i)
}
for i := range []int{1, 2, 3} {
go routineFunc(i)
}
wg.Wait()
fmt.Println("wg.wait")
for res := range resultChannel {
fmt.Println("got from channel,", res)
}
}
运行时会出现错误:
push to channel, 0
push to channel, 1
push to channel, 2
wg.wait
got from channel, 0
got from channel, 1
got from channel, 2
fatal error: all goroutines are asleep - deadlock!
原因是:for range是阻塞式读取channel,只有channel close之后才会结束,否则会一直读取,通道里没有值了,还继续读取就会阻塞,程序就会报死锁。
改成如下即可:
package main
import "sync"
import "fmt"
func main() {
var wg sync.WaitGroup
wg.Add(3)
resultChannel := make(chan int, 3)
routineFunc := func(i int) {
defer wg.Done()
resultChannel <- i
fmt.Println("push to channel,", i)
}
for i := range []int{1, 2, 3} {
go routineFunc(i)
}
wg.Wait()
close(resultChannel)
fmt.Println("wg.wait")
for res := range resultChannel {
fmt.Println("got from channel,", res)
}
}