简体   繁体   English

缓冲/无缓冲通道

[英]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: 一般来说,正如您已经提到的,有两种类型的渠道:

  • buffered which block if the buffer is full. 如果缓冲区已满,则缓冲哪个块。
  • unbuffered which block if there's no "rendezvous", ie there must be someone who puts ( 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM