Sobes.tech
Назад к вопросам
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)

Во всех случаях достигается корректное увеличение счетчика без гонок.