去频道读取并发和阻塞

时间:2018-10-17 19:05:18

标签: go

import "fmt"

func sum(s []int, c chan int) {
    sum := 0
    for _, v := range s {
        sum += v
    }
    c <- sum // send sum to c
}

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

    c := make(chan int)
    go sum(s[:len(s)/2], c)
    go sum(s[len(s)/2:], c)
    x, y := <-c, <-c // receive from c

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

您好,这是官方网站上频道使用的示例。

该示例开始了2个go例程,以计算子数组的总和。然后将其写入int通道。

这行真的让我感到困惑。

x, y := <-c, <-c // receive from c

我的理解是,当第一个例程写入通道时,应阻止第二个例程的写入,然后main将值读取到x(或y)。然后第二个例程写入通道,main读取x(或y)。

这个假设正确吗?

如何判断哪个结果是x或y?

如果第二个例程永不结束,主线是否在这一行被阻塞?

先谢谢了。在这里去菜鸟。

1 个答案:

答案 0 :(得分:1)

  

我的理解是,当第一个例程写入通道时,应阻止第二个例程的写入,然后main将值读取到x(或y)。然后第二个例程写入通道,main读取x(或y)。

正确,因为它没有缓冲。如果通道已缓冲,则这两个例程都可以写入该通道而不会阻塞,直到缓冲区已满。

  

如何判断哪个结果是x或y?

它“决定”产生的词法顺序-读取的第一个值进入第一个变量x,第二个值进入第二个变量y

  

如果第二个例程永不结束,主线是否在这一行被阻塞?

不。它会阻塞,直到将值写入通道为止,而不管写入该通道的goroutine是否仍在运行(实际上,例程可以继续运行并将值永远写入该通道)。