Назад к вопросам
Middle+
5
Что не так с кодом инкремента счетчика в 1000 горутинах? Как исправить через mutex, atomic или каналы?
Компании, где спрашивали
МВидео/эльдорадо
Ответ от нейросети
sobes.tech AI
Проблема с инкрементом счетчика в 1000 горутинах в том, что операция counter++ не атомарна и может привести к гонкам данных (data race), из-за чего итоговое значение счетчика будет меньше ожидаемого.
Исправление через mutex:
var mu sync.Mutex
counter := 0
wg := sync.WaitGroup{}
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
mu.Lock()
counter++
mu.Unlock()
}()
}
wg.Wait()
Исправление через atomic:
var counter int64
wg := sync.WaitGroup{}
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
atomic.AddInt64(&counter, 1)
}()
}
wg.Wait()
Исправление через каналы:
counter := 0
ch := make(chan struct{})
wg := sync.WaitGroup{}
// Горутинка, которая будет увеличивать счетчик
go func() {
for range ch {
counter++
}
}()
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
ch <- struct{}{}
}()
}
wg.Wait()
close(ch)
Во всех случаях достигается корректное увеличение счетчика без гонок.