Sobes.tech
Middle

In what cases can a deadlock occur?

sobes.tech AI

Answer from AI

In Golang, deadlocks most often occur when working with mutexes and channels.

Possible cases:

  • Cyclic dependency of mutexes: Two or more goroutines try to acquire locks on mutexes in different orders, creating a deadlock.

    // goroutine 1
    mu1.Lock()
    mu2.Lock() // waits for mu2, which is held by goroutine 2
    
    // goroutine 2
    mu2.Lock()
    mu1.Lock() // waits for mu1, which is held by goroutine 1
    
  • Blocking send on a non-buffered channel that no one reads: A goroutine sends data to a channel, but no other goroutine is ready to receive it.

    ch := make(chan int)
    ch <- 1 // blocks forever if there is no receiver
    
  • Blocking read from a channel that no one writes to: A goroutine tries to read data from a channel, but no one sends data to it.

    ch := make(chan int)
    <-ch // blocks forever if there is no sender
    
  • Using the same mutex in a recursive function without RWMutex:

    var mu sync.Mutex
    
    func recursiveFunc() {
        mu.Lock() // attempt to lock the same mutex again
        // ...
        // mu.Unlock() // will never be reached
    }
    
  • Sending to or reading from a closed channel without checking: Sending to a closed channel causes a panic, reading from a closed channel returns the zero value and false, but if the second return value is not checked, it can lead to incorrect handling and potential deadlock elsewhere.

  • Incorrect use of sync.WaitGroup: For example, calling Done() before the necessary number of Add() calls, or calling Wait() before all goroutines have finished.

Table with examples:

Situation Mechanism Example
Cyclic dependency of mutexes sync.Mutex Goroutine A waits for B, Goroutine B waits for A
Blocking send on a channel Unbuffered channel ch <- data without a receiver
Blocking read from a channel Channel <-ch without a sender
Recursive use of mutex sync.Mutex Re-locking the same mutex in the same goroutine
Working with a closed channel without check Channel Sending to a closed channel
Incorrect use of WaitGroup sync.WaitGroup Errors in Add/Done/Wait logic