同一个 Channel 中的两个 goroutine - 它们是如何执行的?

Two goroutine in the same Channel - how are they executed?

当我从golang.org开始Golang之旅时,有一个代码片段我不明白:

func sum(a []int, c chan int, order int) {
    sum := 0
    for _, v := range a {
        sum += v
    }
    fmt.Println(order, a)
    c <- sum // 将和送入 c
}

func main() {
    a := []int{7, 2, 8, -9, 4, 0}

    c := make(chan int)
    a1, a2 := a[:len(a)/2], a[len(a)/2:]

    go sum(a1, c, 1)
    x := <-c
    go sum(a2, c, 2)
    y := <-c
    //x := <-c
    //y := <-c
    // x, y := <-c, <-c // 从 c 中获取

    fmt.Println(x, y, x+y)
}

这是我预期的输出:

1 [7 2 8]
2 [-9 4 0]
17 -5 12

当我更改代码时:

func main() {
    a := []int{7, 2, 8, -9, 4, 0}

    c := make(chan int)
    a1, a2 := a[:len(a)/2], a[len(a)/2:]

    go sum(a1, c, 1)
    //x := <-c
    go sum(a2, c, 2)
    //y := <-c
    x := <-c
    y := <-c
    // x, y := <-c, <-c // 从 c 中获取

    fmt.Println(x, y, x+y)
}

为什么输出是这样的:

2 [-9 4 0] 
1 [7 2 8]
-5 17 12

让我来帮你。

在你的第二种情况下:

2 [-9 4 0] 
1 [7 2 8]
-5 17 12

如您所见,第二个 goroutine 比第一个 goroutine 执行得更快,结果我们有 x = 第二个 goroutine (-5) 的结果。

当你使用 go 关键字执行 运行 function/method 时,它会 运行s 并发,这意味着主函数不会等待它执行(如果不使用 sync.WaitGroup{}select{})。

您可以从文档中找到更多详细信息: https://golang.org/pkg/sync/#WaitGroup

问题是你错过了并发的概念 无法保证按照使用 go

调用它们的确切顺序执行函数

第一个代码片段有序运行的原因是 x := <-c 部分 此行强制您的应用程序等待,直到 c 通道充满数据,因此不会调用第二个 goroutine