在下面的代码中,当我们在每个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
。
1条答案
按热度按时间ubby3x7f1#
在第一个例子中,你正在创建what in Go is called a "pipeline"。每个goroutine都有一组唯一的输出和输入通道。每个goroutine的输入都是前一个goroutine的输出。因此,每个goroutine都必须实际执行
<-ch
才能返回一个值。在第二种情况下,所有的goroutine共享
b
,也就是ch
。只要一个goroutine执行,<-ch
就可以阅读。由于goroutine调度程序的行为,这种行为看起来是一致的,但这实际上只是偶然的。