首页 文章

缓冲/无缓冲通道

提问于
浏览
8

有人可以解释,为什么如果通道被缓冲,程序不会以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.

谢谢!

3 回答

  • 2

    如果缓冲区中有空间,则写入缓冲通道不会阻止 .

    如果您尝试在缓冲区大小为1的通道中放入两个项目,则会出现相同的错误:

    package main
    
    func main() {
        c := make(chan int, 1)
        c <- 3
        c <- 4
    }
    

    给你:

    fatal error: all goroutines are asleep - deadlock!
    
  • 11

    它阻止了's a core concept of Go'的通道(或其他CSP实现,如Clojure的core.async库) . 一般来说,正如您已经提到的,有两种类型的渠道:

    如果缓冲区已满,则

    • 缓冲哪个块 .

    • 无缓冲,如果没有"rendezvous"阻止哪个阻塞,即必须有人将( c <- )放入( c <- )并从该 Channels 获取( <- c ) .

    在您的特定情况下,Go运行时足够聪明,可以检测到没有人会从通道 c 中获取 3 . 因此,它是一个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
    
  • 3

    谢谢@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.

相关问题