具有通道参数的函数中的死锁
Deadlock in function which has a channel parameter
给定以下简单的 Go 程序:
ch := make(chan int)
go fmt.Println(<- ch)
ch <- 2
如果我用 go func(){fmt.Println(<-ch)}()
替换 go 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
被评估。但它不能,因为通道是空的,因此它会阻塞,直到有东西写入它。但是从来没有任何东西写入它,因此这是一个死锁。
当您将其包装在匿名函数中时 - 发生同样的情况,但对于匿名函数。然后它的主体被同时评估到主 goroutine。
给定以下简单的 Go 程序:
ch := make(chan int)
go fmt.Println(<- ch)
ch <- 2
如果我用 go func(){fmt.Println(<-ch)}()
替换 go 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
被评估。但它不能,因为通道是空的,因此它会阻塞,直到有东西写入它。但是从来没有任何东西写入它,因此这是一个死锁。
当您将其包装在匿名函数中时 - 发生同样的情况,但对于匿名函数。然后它的主体被同时评估到主 goroutine。