go runtime_error ai_generated true

fatal error: all goroutines are asleep - deadlock! (unbuffered channel)

ID: go/unbuffered-channel-blocking

Also available as: JSON · Markdown · 中文
80%Fix Rate
86%Confidence
0Evidence
2024-09-05First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.20 active
1.21 active
1.22 active

Root Cause

An unbuffered channel requires both sender and receiver to be ready simultaneously. If only one side is ready, it blocks indefinitely.

generic

中文

无缓冲通道要求发送方和接收方同时就绪。如果只有一方就绪,就会无限期阻塞。

Workarounds

  1. 90% success Ensure both sender and receiver are started before the blocking operation
    ch := make(chan int)
    
    go func() {
        val := <-ch
        fmt.Println(val)
    }()
    
    ch <- 42 // now this won't block because receiver is ready
  2. 80% success Use a buffered channel with a reasonable capacity
    ch := make(chan int, 10) // buffer size 10

Dead Ends

Common approaches that don't work:

  1. Making the channel buffered with a small size 50% fail

    A small buffer may not be sufficient; if the buffer fills up, the same deadlock can occur.

  2. Using time.Sleep to give the other side time to prepare 75% fail

    Sleeping is non-deterministic and doesn't guarantee both sides are ready; it may still deadlock.