Материал проходит вычитку — возможны неточности.
Урок 102 из 118

Data race vs race condition

На ревью Миша и Аня спорили о биллинге: доступ везде под мьютексом, а баланс клиента уходил в минус. Аня развела два термина: баг конфигурации — data race, а счёт биллинга — логическая гонка, с которой мьютекс не справился.

Главная мысль

data race — конкретный класс несинхронизированного доступа к памяти, race condition — широкий класс ошибок порядка операций; детектор ловит первое и не видит второе.

Data race

Go

Два обращения к памяти без happens-before, одно из них запись. Это data race — формальная ошибка, ловится race detector'ом. Программа некорректна: исходы ограничены моделью памяти, но ничего хорошего не гарантировано — гонка всегда баг.

Race condition

mu.Lock()
enough := balance >= amount // проверка
mu.Unlock()

if enough {
    mu.Lock()
    balance -= amount // списание — уже в другой секции
    mu.Unlock()
}

Всё под мьютексом — data race нет, детектор молчит. Но между «проверил баланс» и «списал» может вклиниться другая горутина и изменить баланс: решение принято по устаревшему состоянию, и баланс уходит в минус. Ошибка порядка операций при формально синхронизированном доступе — это race condition. Детектор её не видит: формально всё синхронизировано.

Разведём термины: race condition — широкий класс ошибок порядка операций; data race — конкретный класс несинхронизированного доступа к памяти. Классы не совпадают: поучительнее всего логическая гонка без data race — ровно то, что показывает этот пример.

Почему их путают

Обе — про конкурентность, обе проявляются «иногда». Разница — в уровне: data race — про то, как горутины обращаются к памяти (формально, машинно проверяемо), race condition — про то, что код делает с данными (семантически, проверяется только головой). Данные могут быть идеально защищены от гонок — и всё равно иметь логическую гонку между операциями.

В следующем уроке

Вы узнаете:

  • почему -race не сертификат корректности
  • какие реальные примеры check-then-act в сервисах
Задание · вопросы

Проверьте себя

Вопрос 1 из 3

Два атомика total и count обновляются парой, а читаются по отдельности. Что это?

Вопрос 2 из 3

Кто ловит логическую гонку (race condition)?

Вопрос 3 из 3

«Всё под одним мьютексом» — достаточное условие корректности?

Итоги

Data race — несинхронизированный доступ, ловится инструментами. Race condition — неверный порядок операций, ловится ревью и тестами: логическая гонка возможна и без data race. Мьютекс закрывает первое, но не второе.

Наш сайт собирает куки. Чтобы тебе было удобнее им пользоваться. Нажимая на кнопку, ты даёшь разрешение собирать куки