问题描述
我正在学习Go,并且遇到了以下代码段:
I'm learning Go, and have run across the following code snippet:
package main
import "fmt"
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int, 2)
go sum(a[0:3], c)
go sum(a[3:6], c)
x := <-c
y := <-c
// x, y := <-c, <-c // receive from c
fmt.Println(x, y)
}
Output:
-5 17
Program exited.
有人可以告诉我为什么 sum函数的第二次调用之前通过该通道吗第一个?在我看来,输出应为:
Can someone please tell me why the 2nd calling of the "sum" function is coming through the channel before the 1st one? It seems to me that the output should be:
17 -5
我也用无缓冲通道测试了它,它也给出了相同的输出顺序。我缺少什么?
I've also tested this with an un-buffered channel and it also gives the same order of output. What am I missing?
推荐答案
您正在代码中调用go例程,但无法确定例程何时结束
You are calling the go routine in your code and you can't tell when the routine will end and the value will be passed to the buffered channel.
由于该代码是异步的,因此每当例程完成时,它将把数据写入通道并继续读取。另一边。在上面的示例中,您仅调用了两个go例程,因此行为是确定的,并且在大多数情况下都会以某种方式生成相同的输出,但是当您增加go例程时,输出将不会相同,并且顺序会有所不同,除非您执行以下操作
As this code is asynchronous so whenever the routine will finish it will write the data to the channel and will be read on the other side. In the example above you are calling only two go routines so the behavior is certain and same output is generated somehow for most of the cases but when you will increase the go routines the output will not be same and the order will be different unless you make it synchronous.
示例:
package main
import "fmt"
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 2, 4, 2, 8, 2, 7, 2, 99, -32, 2, 12, 32, 44, 11, 63}
c := make(chan int)
for i := 0; i < len(a); i = i + 5 {
go sum(a[i:i+5], c)
}
output := make([]int, 5)
for i := 0; i < 4; i++ {
output[i] = <-c
}
close(c)
fmt.Println(output)
}
[12 18 0 78 162]
[162 78 12 0 18]
[12 18 78 162 0]
这是因为goroutines异步写入了输出
This is because the goroutines wrote the output asynchronously to the buffered channel.
希望这会有所帮助。
这篇关于Golang频道,执行顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!