Search code examples
gochannelgoroutine

Why does sending a value more than buffered channel size in Golang causes deadlock error?


// By default channels are _unbuffered_, meaning that they
// will only accept sends (`chan <-`) if there is a
// corresponding receive (`<- chan`) ready to receive the
// sent value. _Buffered channels_ accept a limited
// number of  values without a corresponding receiver for
// those values.

package main

import "fmt"

func main() {

    // Here we `make` a channel of strings buffering up to
    // 2 values.
    messages := make(chan string, 2)

    // Because this channel is buffered, we can send these
    // values into the channel without a corresponding
    // concurrent receive.
    messages <- "buffered"
    messages <- "channel"
    messages <- "channel1" //I added this. 

    // Later we can receive these two values as usual.
    fmt.Println(<-messages)
    fmt.Println(<-messages)
}

Error it throws:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    /tmp/sandbox795158698/prog.go:23 +0x8d

Questions:

  1. Can't we send more values than buffer size?
  2. Why the error says "all goroutines are asleep - deadlock!" when there are no goroutines here in the code?
  3. Why is it this a deadlock? Please explain?

PlayGroundLink


Solution

  • An attempt to write to a full channel will block until some other goroutine reads from it. In your program, there are no other goroutines. So when you write to the full channel, the main goroutine blocks, and since there are no other goroutines, there is no chance that the main goroutine ever can progress. That is a deadlock.