example:
package main
import (
"fmt"
"sync"
)
func main() {
Test_0()
}
func Test_0() {
//fmt.Println("123")
c1 := make(chan bool, 1)
c2 := make(chan bool, 1)
c1 <- true
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
for i := 0; <-c1 && i < 10; i += 2 {
fmt.Printf("%v \n", i)
c2 <- true
}
wg.Done()
}()
go func() {
for i := 1; i < 10 && <-c2; i += 2 {
fmt.Printf("%v\n", i)
c1 <- true
}
wg.Done()
}()
wg.Wait()
}
运行结果:
B-LAJ9LVDL-1650:0316 dsong$ go run main02.go
0
1
2
3
4
5
6
7
8
9
如果修改两个for循环中的判断条件顺序:
go func() {
for i := 0; i < 10 && <-c1; i += 2 {
fmt.Printf("%v \n", i)
c2 <- true
}
wg.Done()
}()
go func() {
for i := 1; <-c2 && i < 10; i += 2 {
fmt.Printf("%v\n", i)
c1 <- true
}
wg.Done()
}()
运行结果:
0
1
2
3
4
5
6
7
8
9
fatal error: all goroutines are asleep - deadlock!
原因就是循环判定中读channel的顺序问题,由左到右,所以第二段代码的i=9时,执行c1 <-true,但是c1中i=10,跳出了循环,所以<-c2就陷入了deadlock导致报错。
可以加个close(c)
go func() {
for i := 0; <-c1 && i < 3; i += 2 {
fmt.Printf("%v \n", i)
c2 <- true
}
wg.Done()
close(c2)
}()
go func() {
for i := 1; i < 3 && <-c2; i += 2 {
fmt.Printf("%v\n", i)
c1 <- true
}
wg.Done()
close(c1)
}()
wg.Wait()