package main
import (
"fmt"
"time"
)
func main() {
done := make(chan bool)
go func() {
for {
select {
case <-done:
fmt.Println("here")
}
}
}()
go func() {
q := time.NewTimer(time.Second)
<-q.C
done <- true
}()
<-done
fmt.Println("closing")
}
我的问题是,done
通道是否被goroutine而非主goroutine占用。
该程序将被阻止。
但事实是该程序从未被阻止。主goroutine似乎每次都被done
通道占用。
为什么?
答案 0 :(得分:0)
虽然,我没有在文档中找到答案,但看起来像接收值的例程首先尝试从通道读取。在我们的例子中,总是使用main
方法几乎总是达到<-done
(99.0%),因为例程开始异步运行并且需要一段时间才能运行。但是无论如何,我强烈建议您不要依赖于此,因为这不能保证。
为演示它,请看以下示例:
package main
import (
"fmt"
"time"
)
func main() {
done := make(chan bool)
n := 5
for i := 0; i < n; i++ {
go func(i int) {
fmt.Println(i, "Waiting to read")
<-done
fmt.Println(i, "DONE")
}(i)
time.Sleep(time.Second)
}
time.Sleep(time.Second)
for i := 0 ; i < n; i++ {
time.Sleep(time.Second)
done <- true
}
time.Sleep(time.Second)
}
将产生输出
0 Waiting to read
1 Waiting to read
2 Waiting to read
3 Waiting to read
4 Waiting to read
0 DONE
1 DONE
2 DONE
3 DONE
4 DONE