我正在学习 Go 语言。有人可以解释这里的输出吗?
package main
import "fmt"
var c = make(chan int, 1)
func f() {
c <- 1
fmt.Println("In f()")
}
func main() {
go f()
c <- 2
fmt.Println(<-c)
fmt.Println(<-c)
}
输出:
In f()
2
1
Process finished with exit code 0
为什么“In f()”出现在“2”之前?如果在“2”之前打印“In f()”,则缓冲通道应阻塞。但这并没有发生,为什么呢?
其他输出是合理的。
导致此运行的事件顺序如下:
2
频道。通道的容量现已耗尽。1
频道。导致死锁的事件顺序如下:
1
频道。通道的容量现已耗尽。2
频道。由于通道的缓冲区已满,因此会阻塞。您提供的输出似乎表明 goroutine 首先完成并且程序没有死锁,这与上述两种情况的解释相矛盾。但这就是发生的事情:
2
频道。2
从频道阅读。1
频道。In f()
。2
从通道接收到的。1
从频道阅读。1
从通道接收到的。请记住,除非您以编程方式强制执行,否则您对 goroutine 的调度没有任何保证。当您启动一个 goroutine 时,该 goroutine 的第一个代码何时实际执行以及启动代码在此之前的进度是不确定的。请注意,由于您的代码依赖于特定的事件顺序,因此它被该定义打破,只是明确地说。
此外,在程序中的任何时候,调度程序都可以决定在不同的 goroutine 之间切换。甚至单行也fmt.Printtln(<-c)
包含多个步骤,并且在每个步骤之间可以发生切换。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句