给定以下简单的 Go 程序:
ch := make(chan int)
go fmt.Println(<- ch)
ch <- 2
如果我替换 go fmt.Println(<- ch)
与 go func(){fmt.Println(<-ch)}()
, 效果很好。
但是对于原始版本我得到:
fatal error: all goroutines are asleep - deadlock!
为什么?
最佳答案
如 spec 中所定义:
The function value and parameters are evaluated as usual in the calling goroutine, but unlike with a regular call, program execution does not wait for the invoked function to complete. Instead, the function begins executing independently in a new goroutine. When the function terminates, its goroutine also terminates. If the function has any return values, they are discarded when the function completes.
所以 <-ch
被评估。但它不能,因为 channel 是空的,因此它会阻塞,直到有东西写入它。但是从来没有任何东西写入它,因此这是一个死锁。
当您将其包装在匿名函数中时 - 会发生同样的情况,但对于匿名函数。然后它的主体被同时评估到主 goroutine。
关于go - 具有 channel 参数的函数中的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55195033/