Skip to content

Latest commit

 

History

History
64 lines (39 loc) · 5.03 KB

File metadata and controls

64 lines (39 loc) · 5.03 KB

Гонка данных (или Data Race) — это критическая ошибка в многопоточном программировании, которая возникает, когда несколько потоков одновременно обращаются к одной и той же области памяти, и при этом хотя бы один из них выполняет запись.

Проще говоря, это ситуация, когда результат выполнения программы зависит от того, какой поток «успеет» первым, что делает поведение приложения непредсказуемым.


Три условия возникновения

Гонка данных происходит только тогда, когда одновременно соблюдаются три условия:

  1. Многопоточность: Два или более потока обращаются к одной переменной.
  2. Общая память: Они используют одну и ту же область памяти (общую переменную).
  3. Отсутствие синхронизации: Потоки не используют специальные инструменты (например, мьютексы), чтобы договориться об очередности, и как минимум один поток записывает данные.

Классический пример: Счётчик в банке

Представьте, что у вас есть общий счет, на котором лежит 100$. Два потока одновременно пытаются прибавить к нему по 10$.

Что происходит на низком уровне:

  1. Поток А считывает значение (100).
  2. Поток Б считывает значение (100).
  3. Поток А прибавляет 10 и получает 110.
  4. Поток Б прибавляет 10 и получает 110.
  5. Поток А записывает 110 в память.
  6. Поток Б записывает 110 в память.

Итог: Вместо ожидаемых 120$ на счету осталось 110$, потому что один поток «затер» изменения другого.


Почему это опасно?

  • Нестабильность: Ошибка может не проявляться при тестировании на вашем компьютере, но «выстрелить» на сервере под большой нагрузкой.
  • Сложность отладки: Поведение программы меняется от запуска к запуску (эффект Гейзенбага).
  • Порча данных: Вы можете получить значения, которые вообще не должны существовать в логике программы.

Как бороться с гонкой данных?

Для предотвращения гонок используют механизмы синхронизации:

Метод Как это работает
Мьютексы (Mutex) Поток «бронирует» переменную. Пока он с ней работает, остальные ждут своей очереди.
Атомарные операции Операции (например, инкремент), которые выполняются как одно неделимое действие на уровне процессора.
Immutable объекты Сделать данные неизменяемыми. Если нельзя ничего записывать — гонки не будет.
Thread Locality Использование локальных данных для каждого потока, чтобы они не пересекались.

Разница между Data Race и Race Condition

Их часто путают, но это разные вещи:

  • Data Race: Конкретно про доступ к памяти (то, что описано выше).
  • Race Condition (Состояние гонки): Более широкое понятие. Это ошибка в логике или порядке событий. Например, вы сначала удаляете файл в одном потоке, а в другом пытаетесь его прочитать. Даже если доступ к памяти защищен, логика сломается из-за неверного порядка.

Хотите, я покажу пример кода на конкретном языке программирования (например, Python, C++ или Java), чтобы продемонстрировать, как исправить такую ошибку?