[英]Why goroutine channel does this?
我是 golang 的新手。 我试图了解渠道是如何工作的,但这真的很令人困惑。
我评论了我的问题。 有人可以向我解释为什么这段代码会以这种奇怪的方式运行吗?
package main
import "fmt"
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
c := make(chan int)
go pokeVals(slice, c)
fmt.Println(slice)
fmt.Println("start")
<-c // why 2 "poke"s here?
fmt.Println("-")
<-c // why 0 "poke"s?
//<-c // But if uncommented - 2 more "pokes" here
fmt.Println("end")
}
func pokeVals(values []int, c chan int) {
for _, val := range values {
fmt.Println("poke")
c <- val
}
fmt.Println("overpoked")
}
Golang 游乐场链接: https : //play.golang.org/p/u__cVyUbNJY
Goroutines 并发运行。 它们的调度方式不受您的控制,唯一的保证是您是否使用同步,例如通道、等待组或其他同步原语。
从main()
启动一个 goroutine,它在循环中发送c
上的值。 但是在发送每个值之前,它首先打印"poke"
。 因此,即使您没有收到来自c
您也可能会看到打印了一个"poke"
。 如果你确实从c
接收到一个值,那么这个 goroutine 中的循环可以继续下一次迭代,再次打印"poke"
,它可能会立即打印,甚至在main()
goroutine 开始打印"-"
。 这就是你所经历的。
原始版本中的main()
协程(第 3 个<-c
注释掉)终止(在打印"end"
)。 一旦main()
返回,您的应用程序就结束了,它不会等待其他 goroutines 完成。 这就是你所经历的。 有关详细信息,请参阅goroutine 无输出。
如果您取消注释第三个<-c
,则main()
必须在c
上等待另一个发送,这意味着它肯定必须在此之前等待"poke"
打印。 一旦pokeVals()
的 goroutine 能够在c
上发送另一个值,它可能会在下一次迭代的循环中再次打印"poke"
(如果这被安排在从main()
返回之前),这就是您所经历的。
您是否看到 2 个额外的"poke"
打印是不确定的,其中 1 或 2 个都是有效结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.