Golang中的通道分配究竟是如何工作的?

b1payxdu  于 2023-11-14  发布在  Go
关注(0)|答案(1)|浏览(81)

在下面的代码中,当我们在每个go例程调用之后添加b = a时,从ch通道接收的值是4

package main

import "fmt"

func main() {
    ch := make(chan int)
    a := ch
    b := ch

    a = make(chan int)
    go f(a, b)
    b = a

    a = make(chan int)
    go f(a, b)
    b = a

    a = make(chan int)
    go f(a, b)
    b = a

    go func() { a <- 1 }()
    fmt.Println(<-ch)
}

func f(a, b chan int) {
    b <- 1 + <-a
}

字符串
另一方面,在下面的代码中,当我们在每个go例程调用后删除b = a时,从ch通道接收的值是2

package main

import "fmt"

func main() {
    ch := make(chan int)
    a := ch
    b := ch

    a = make(chan int)
    go f(a, b)

    a = make(chan int)
    go f(a, b)

    a = make(chan int)
    go f(a, b)

    go func() { a <- 1 }()
    fmt.Println(<-ch)
}

func f(a, b chan int) {
    b <- 1 + <-a
}


有人能解释一下为什么会发生这种情况吗?我也想知道b = a在这里的行为到底如何。
根据我的预期,在上述两种情况下,行为应该是相同的,来自ch通道的值应该是2

ubby3x7f

ubby3x7f1#

在第一个例子中,你正在创建what in Go is called a "pipeline"。每个goroutine都有一组唯一的输出和输入通道。每个goroutine的输入都是前一个goroutine的输出。因此,每个goroutine都必须实际执行<-ch才能返回一个值。
在第二种情况下,所有的goroutine共享b,也就是ch。只要一个goroutine执行,<-ch就可以阅读。由于goroutine调度程序的行为,这种行为看起来是一致的,但这实际上只是偶然的。

相关问题