Sobes.tech
Back to questions
Junior — Middle
80

Каким образом можно предотвратить взаимную блокировку при использовании двух мьютексов?

Answer from AI

sobes.tech AI

Чтобы предотвратить взаимную блокировку (deadlock) при использовании двух мьютексов в Go, нужно соблюдать порядок захвата мьютексов во всех горутинах. То есть всегда блокировать мьютексы в одном и том же порядке. Например, если есть мьютексы mu1 и mu2, то везде сначала берём mu1, затем mu2. Это исключит ситуацию, когда одна горутина ждёт mu2, а другая — mu1, и обе блокируются.

Пример:

var mu1, mu2 sync.Mutex

func f() {
    mu1.Lock()
    defer mu1.Unlock()

    mu2.Lock()
    defer mu2.Unlock()

    // критическая секция
}

func g() {
    mu1.Lock()  // обязательно сначала mu1
    defer mu1.Unlock()

    mu2.Lock()
    defer mu2.Unlock()

    // критическая секция
}

Если порядок захвата мьютексов будет разным, возможен deadlock. Также можно использовать таймауты или try-lock механизмы, но в Go стандартный sync.Mutex не поддерживает try-lock, поэтому главное — единый порядок блокировок.