Sobes.tech
Junior — Middle

What is a deadlock when using goroutines and how can it be avoided?

sobes.tech AI

Answer from AI

A deadlock in the context of goroutines is a situation where two or more goroutines block each other forever, waiting for resources held by each other. For example, if goroutine A waits for a resource held by goroutine B, and goroutine B waits for a resource held by goroutine A, a deadlock occurs.

In Go, this can manifest when channels or mutexes are used improperly. For instance, if a goroutine tries to send data to a channel but no one is reading from it, or if multiple goroutines attempt to acquire mutexes in different orders.

How to avoid deadlocks:

  • Avoid cyclic dependencies when acquiring multiple mutexes — always acquire them in the same order.
  • Use buffered channels to prevent blocking during send operations when appropriate.
  • Apply timeouts and contexts (context.Context) to cancel operations if waiting is prolonged.
  • Minimize blocking operations and design architecture so that goroutines do not depend on each other directly.

Example of a simple deadlock situation with channels:

ch := make(chan int)

func main() {
    go func() {
        ch <- 1 // blocks because no one is reading
    }()
    // main does not read from ch, goroutine is forever blocked
}

To avoid this, read from the channel:

ch := make(chan int)

func main() {
    go func() {
        ch <- 1
    }()
    val := <-ch // reading unblocks the goroutine
    fmt.Println(val)
}
What is a deadlock when using goroutines and how can… - sobes.tech