Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Golang: data race, race condition, goroutine, mutex, race detector

Что такое data race и как его обнаружить в Go-программе?

Вопрос проверяет понимание проблемы гонки данных (data race) в многопоточных Go-программах и знание инструментов для её обнаружения.

Короткий ответ

Data race возникает, когда две или более горутины одновременно обращаются к одной переменной, и хотя бы одна из них выполняет запись. Это приводит к непредсказуемому поведению программы. В Go для обнаружения гонок используется встроенный race detector, который запускается с флагом -race при компиляции или тестировании. Он отслеживает несинхронизированные доступы к памяти и выводит предупреждения.

Длинный ответ

Что такое data race?

Data race (гонка данных) — это ситуация в многопоточном программировании, когда несколько потоков (в Go — горутин) одновременно обращаются к одной и той же переменной, и хотя бы один из доступов является записью. При этом отсутствует синхронизация (например, с помощью мьютексов или каналов), что приводит к неопределённому поведению программы. Результат может зависеть от порядка выполнения потоков, который не гарантирован.

Пример data race в Go

package main

import (
	"fmt"
	"sync"
)

var counter int

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			counter++ // гонка: несколько горутин пишут в counter
		}()
	}
	wg.Wait()
	fmt.Println(counter) // результат непредсказуем
}

В этом примере 1000 горутин одновременно увеличивают счётчик без синхронизации. Ожидаемый результат — 1000, но из-за гонки данных он может быть меньше.

Как обнаружить data race?

Go предоставляет встроенный race detector. Для его активации нужно добавить флаг -race при компиляции, запуске или тестировании:

go run -race main.go
go test -race ./...

Race detector анализирует все обращения к памяти и сообщает о потенциальных гонках. Он использует технологию отслеживания доступа (happens-before) и выводит подробный стек вызовов для каждого конфликтующего доступа.

Как исправить data race?

Для устранения гонки данных нужно синхронизировать доступ к общим данным. В Go это делается с помощью:

  • Мьютексов (sync.Mutex) — блокируют доступ к критической секции.
  • Каналов — передача данных через каналы гарантирует синхронизацию.
  • Атомарных операций (sync/atomic) — для простых типов данных.

Исправленный пример с мьютексом:

package main

import (
	"fmt"
	"sync"
)

var (
	counter int
	mu      sync.Mutex
)

func main() {
	var wg sync.WaitGroup
	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			mu.Lock()
			counter++
			mu.Unlock()
		}()
	}
	wg.Wait()
	fmt.Println(counter) // всегда 1000
}

Вывод

Data race — серьёзная проблема в многопоточных программах, приводящая к недетерминированным ошибкам. В Go её легко обнаружить с помощью race detector, который следует использовать при разработке и тестировании. Для предотвращения гонок применяйте синхронизацию через мьютексы, каналы или атомарные операции. Это особенно важно в высоконагруженных системах, где параллелизм критичен.

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • Golang

    Golang

Ключевые слова

#data race

#race condition

#goroutine

#mutex

#race detector

Подпишись на Golang Developer в телеграм

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.