Race condition — когда две горутины одновременно обращаются к одной переменной и хотя бы одна пишет. Результат непредсказуем.
counter := 0
for i := 0; i < 1000; i++ {
go func() {
counter++ // DATA RACE — read + write без синхронизации
}()
}
Способы защиты:
// 1. Мьютекс
var mu sync.Mutex
mu.Lock()
counter++
mu.Unlock()
// 2. Атомарные операции
var counter int64
atomic.AddInt64(&counter, 1)
// 3. Каналы (передача владения)
ch := make(chan int, 1)
ch <- counter
val := <-ch
Детектор гонок — встроен в Go:
go run -race main.go
go test -race ./...
Запускай -race в CI — он находит гонки в рантайме. В production не используй (замедляет ~10x).