[英]channel consume order in different goroutine
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")
}
My question is if done
channel is consumed by goroutine not main goroutine. 我的问题是,已done
通道是否由goroutine而非主要goroutine占用。 the program will be blocked. 该程序将被阻止。
But the fact is that the program never be blocked.main goroutine seem to be consumed the done
channel everytime. 但是事实是程序永远不会被阻塞。main goroutine似乎每次都在done
通道中被消耗掉。
Why? 为什么?
Although, I didn't found answer in docs, looks like receives value the routine which first tried to read from the channel. 虽然,我没有在文档中找到答案,但看起来像接收值的例程首先尝试从通道读取。 In our case, always main
method is almost always reaching <-done
(99.0%), because routines starts asynchronous and takes a while to run. 在我们的例子中,总是main
方法几乎总是达到<-done
(99.0%),因为例程开始异步运行并且需要一段时间才能运行。 But anyway, I would strongly suggest you do not rely on this, as this is not a guaranteed. 但是无论如何,我强烈建议您不要依赖于此,因为这不能保证。
To demonstrate it, look at the following example: 为了演示它,请看以下示例:
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)
}
Which will produce output 哪个会产生输出
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.