Как избежать Deadlock при работе с потоками

«Как избежать Deadlock при работе с потоками» — вопрос из категории Golang, который задают на 23% собеседований Golang Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Deadlock возникает, когда горутины блокируют друг друга, ожидая ресурсы. Основные способы избежать:

  1. Порядок блокировок – всегда захватывайте мьютексы в одинаковом порядке:
var mu1, mu2 sync.Mutex

// Правильно:
mu1.Lock()
mu2.Lock()
// ...
mu2.Unlock()
mu1.Unlock()
  1. Используйте select с таймаутами для каналов:
select {
case <-ch:
    // получено значение
case <-time.After(1 * time.Second):
    // таймаут
}
  1. Разделяйте ресурсы – проектируйте так, чтобы горутины не зависели сильно друг от друга.

  2. Используйте sync.WaitGroup для ожидания завершения горутин вместо блокировок.

  3. Detect deadlocksgo run -race для обнаружения гонок данных.