Home > other >  Channel deadlocks when I add select default statement in goroutine
Channel deadlocks when I add select default statement in goroutine

Time:11-16

I'm learning channel and below is a test I tried, but deadlock happens

func main() {
    ch := make(chan int)
    go func() {
        select {
        case ch <- 1:
            fmt.Println("send suc")
        default: // if comment this line, it will run smoothly
            fmt.Println("default")
        }
    }()
    time.Sleep(2) // do some time consuming thing...
    fmt.Printf("receive val: %d", <-ch)
}

I expected there is no deadlock, but result is:

default
fatal error: all goroutines are asleep - deadlock!

But if I remove default or time.Sleep(2), code will run smoothly, result:

send suc
receive val: 1

Can someone explain why deadlock happen?

CodePudding user response:

You have a select with default, that means if none of the communication ops are ready, select will not wait, will not block, but execute default immediately. The channel is unbuffered, so the send on it is not ready (because there are no receivers ready – main is sleeping).

So once the sleep is over in main, it tries to receive from the channel, but by then there is nobody trying to send on it. Deadlock.

  • Related