在下面的代码中,当我们在每次 go 例程调用后添加
ch
时,从 4
通道收到的值是 b = a
。
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 例程调用后删除
ch
时,从 2
通道收到的值是 b = a
。
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
。
在第一个示例中,您正在创建 Go 中称为“管道”的东西。每个 goroutine 都有一组独特的输出和输入通道。每个 Goroutine 的输入是前一个 Goroutine 的输出。因此,每个 goroutine 必须实际执行
<-ch
才能返回一个值。
在第二种情况下,所有 goroutine 共享
b
又名 ch
。一旦一个 goroutine 执行,<-ch
就可供读取。由于 Goroutine 调度程序的行为,这种行为看起来是一致的,但这实际上只是偶然。