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
channel 是否由 goroutine 而不是主 goroutine 使用。
该程序将被阻止。
但事实是程序永远不会被阻塞。main goroutine 似乎每次都消耗 done
channel 。
为什么?
最佳答案
尽管我没有在文档中找到答案,但看起来接收值是首先尝试从 channel 读取的例程。在我们的例子中,总是 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
关于go - channel 在不同的 goroutine 中消费顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53426758/