[英]Buffered/Unbuffered channel
Could someone explain, why if the channel is buffered the program doesn't exit with a fatal_error? 有人可以解释一下,为什么如果通道被缓冲,程序不会以fatal_error退出?
Unbuffered channel 无缓冲的频道
package main
func main() {
c := make(chan int)
c <- 3
}
fatal error: all goroutines are asleep - deadlock!
Buffered channel 缓冲频道
package main
func main() {
c := make(chan int, 1)
c <- 3
}
[no output]
Program exited.
Thank you! 谢谢!
Writing to a buffered channel doesn't block if there is room in the buffer. 如果缓冲区中有空间,则写入缓冲通道不会阻止。
If you try to put two items in the channel with a buffer size of one, you get the same error: 如果您尝试将两个项目放在缓冲区大小为1的通道中,则会出现相同的错误:
package main
func main() {
c := make(chan int, 1)
c <- 3
c <- 4
}
gives you: 给你:
fatal error: all goroutines are asleep - deadlock!
It's a core concept of Go's channels (or other CSP implementations such as Clojure's core.async library) that they are blocking. 这是他们阻止的Go的渠道(或其他CSP实现,如Clojure的core.async库)的核心概念。 In general, as you already mentioned, there're two types of channels:
一般来说,正如您已经提到的,有两种类型的渠道:
c <-
) to and someone who takes ( <- c
) from the channel. c <-
以和人谁需要( <- c
)从通道。 In your particular case the Go runtime is smart enough to detect that there's no one who will ever take 3
from channel c
. 在您的特定情况下,Go运行时足够聪明,可以检测到没有人会从通道
c
获取3
。 Hence, it's a deadlock and (thankfully) an error is thrown. 因此,它是一个死锁,并且(幸运的是)抛出了一个错误。
What you typically do when you're working with channels is using goroutines (checkout this introduction ) which spawn a lightweight thread—managed by the Go runtime—to execute the body concurrently: 当你使用频道时,你通常做的是使用goroutines (结束本简介 ),它产生一个由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
Thanks @Matt 谢谢@Matt
I found the answer in this post How does make(chan bool) behave differently from make(chan bool, 1)? 我在这篇文章中找到了答案make(chan bool)与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.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.