为什么这部分代码先于另一部分执行?
Why does this part of the code gets executed before the other?
我是 Go 的新手,我正在尝试了解无缓冲通道和 goroutines。
我有这个代码:
func main() {
var waitGroup sync.WaitGroup
waitGroup.Add(3)
c := make(chan int)
go func() {
defer waitGroup.Done()
x := 1
res := x * 2
fmt.Println(x, "* 2 = ", res)
c <- x
}()
go func() {
defer waitGroup.Done()
x := <-c
res := x * 3
fmt.Println(x, "* 3 = ", res)
c <- x
}()
go func() {
defer waitGroup.Done()
x := <-c
res := x * 4
fmt.Println(x, "* 4 = ", res)
}()
waitGroup.Wait()
close(c)
}
所以我希望输出为:
1 * 2 = 2
1 * 3 = 3
1 * 4 = 4
相反,我得到:
1 * 2 = 2
1 * 4 = 4
fatal error: all goroutines are asleep - deadlock!
我真的不明白为什么第二个函数在第三个函数之后执行。如何在不将频道更改为缓冲频道的情况下获得结果。
您似乎期望 <-
运算符关心 goroutines 的创建顺序。这不是承诺(甚至可能)。如果两个 <-
运算符正在读取同一个通道,则哪个获得值是随机的。如果你想订购这个,你需要创建另一个通道,第二个 goroutine 写入,第三个 goroutine 读取。
缓冲在这里无济于事,因为问题不在于它在写入时阻塞。就是第三个函数消费了一个值,并没有生成一个值,所以第二个函数没有什么可读的。
我是 Go 的新手,我正在尝试了解无缓冲通道和 goroutines。
我有这个代码:
func main() {
var waitGroup sync.WaitGroup
waitGroup.Add(3)
c := make(chan int)
go func() {
defer waitGroup.Done()
x := 1
res := x * 2
fmt.Println(x, "* 2 = ", res)
c <- x
}()
go func() {
defer waitGroup.Done()
x := <-c
res := x * 3
fmt.Println(x, "* 3 = ", res)
c <- x
}()
go func() {
defer waitGroup.Done()
x := <-c
res := x * 4
fmt.Println(x, "* 4 = ", res)
}()
waitGroup.Wait()
close(c)
}
所以我希望输出为:
1 * 2 = 2
1 * 3 = 3
1 * 4 = 4
相反,我得到:
1 * 2 = 2
1 * 4 = 4
fatal error: all goroutines are asleep - deadlock!
我真的不明白为什么第二个函数在第三个函数之后执行。如何在不将频道更改为缓冲频道的情况下获得结果。
您似乎期望 <-
运算符关心 goroutines 的创建顺序。这不是承诺(甚至可能)。如果两个 <-
运算符正在读取同一个通道,则哪个获得值是随机的。如果你想订购这个,你需要创建另一个通道,第二个 goroutine 写入,第三个 goroutine 读取。
缓冲在这里无济于事,因为问题不在于它在写入时阻塞。就是第三个函数消费了一个值,并没有生成一个值,所以第二个函数没有什么可读的。