有人可以解释,为什么如果频道被缓冲,程序不会以fatal_error退出?
无缓冲频道
package main
func main() {
c := make(chan int)
c <- 3
}
fatal error: all goroutines are asleep - deadlock!
缓冲频道
package main
func main() {
c := make(chan int, 1)
c <- 3
}
[no output]
Program exited.
谢谢!
答案 0 :(得分:11)
如果缓冲区中有空间,则写入缓冲通道不会阻止。
如果您尝试在缓冲区大小为1的通道中放入两个项目,则会出现相同的错误:
package main
func main() {
c := make(chan int, 1)
c <- 3
c <- 4
}
给你:
fatal error: all goroutines are asleep - deadlock!
答案 1 :(得分:3)
这是Go的频道(或其他CSP实现,如Clojure的core.async库)的核心概念,它们正在阻止它们。一般来说,正如您已经提到的,有两种类型的渠道:
c <-
)和从中获取(<- c
)的人。 在您的特定情况下,Go运行时足够聪明,可以检测到没有人会从频道3
中获取c
。因此,它是deadlock并且(幸运的是)抛出了一个错误。
当您使用频道时,您通常使用 goroutines (checkout this introduction)来生成由Go运行时管理的轻量级线程,以同时执行主体:
c := make(chan int)
go func() { c <- 3 }() // Create a new gorountine that puts 3 to the channel
fmt.Println(<- c) // Take 3 from the channel and print it in the main thread
答案 2 :(得分:2)
谢谢@Matt
我在这篇文章中找到了答案How does make(chan bool) behave differently from make(chan bool, 1)?:
Actually that's the reason why your problem is generated. Un-buffered channels are only writable when there's someone blocking to read from it, which means you shall have some coroutines to work with -- instead of this single one.