Ответ
Livelock — это ситуация, когда горутины активно работают, но не прогрессируют из-за взаимных блокировок без фактического deadlock. В отличие от deadlock, горутины не заблокированы, а бесконечно реагируют на действия друг друга.
Пример:
var sharedResource int
var mu1, mu2 sync.Mutex
func goroutine1() {
for {
mu1.Lock()
time.Sleep(100 * time.Millisecond) // Имитация работы
if mu2.TryLock() {
sharedResource++
mu2.Unlock()
mu1.Unlock()
break
}
mu1.Unlock()
}
}
func goroutine2() {
for {
mu2.Lock()
time.Sleep(100 * time.Millisecond)
if mu1.TryLock() {
sharedResource--
mu1.Unlock()
mu2.Unlock()
break
}
mu2.Unlock()
}
}
Здесь горутины могут бесконечно пытаться захватить оба мьютекса, но из-за timing'а постоянно пропускать момент, когда оба свободны. Решение — изменить логику синхронизации или добавить случайные задержки.