done:=make(chan struct{})
c:=make(chan int)
go func() {
defer close(done)
for{
s,ok:=<-c
if !ok{
//close(c)
return
}
println(s)
}
}()
for i:=0;i<1 ;i++ {
println("put")
c<-i
}
println("main....")
//close(c)
<-done
当for循环到max+1的时候会出现阻塞问题,为啥B区域的close可以关闭通道,而在A区域无法关闭
go func
协程里的s,ok:=<-c
在一个for
死循环里,第一遍循环阻塞再这里,等待c信号量。main
协程的for循环打印出put
,然后给go func
这个协程发了一个c信号,协程收到这个信号,开始继续执行,if !ok
即为false
所以不会return,此时go func
协程会打印出0。进入下个循环,依旧阻塞在等待c信号量。而main协程走到了
println("main....")
所以能够打印出main...
close(c)
,那么go func
协程阻塞在了等待c信号量上,而main协程阻塞在了等待down信号量,造成了deadlock!
,A区域的close(c)
没有机会走到,所以不会return,不会走到defer,更不会走到close(down)close(c)
,那么main协程暂时阻塞在等待down信号量,go func
接受到了这个c信号量继续走,此时c已经close,所以if !ok
为true,此时可以走到return,跳出for死循环,走到defer函数,走到close(down),发送一个down信号量给main,此时main接着走,完成整个流程。