Sobes.tech
Назад к вопросам
Junior — Middle
55

Как системы обрабатывают ситуацию, когда несколько потоков одновременно обращаются к общей переменной или состоянию?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

При одновременном доступе нескольких потоков к общим данным возникает состояние гонки, и итог зависит от порядка выполнения операций. Для защиты используют синхронизацию: lock, Monitor, Interlocked, Mutex, SemaphoreSlim и другие механизмы. Выбор зависит от того, нужна ли простая защита критической секции, атомарная операция или ограничение числа одновременно работающих потоков.

Определение:

Если несколько потоков читают и особенно изменяют одно и то же состояние без координации, результат становится недетерминированным. Потоки могут “перезаписывать” изменения друг друга, видеть устаревшие значения или ломать инварианты объекта. Чтобы этого избежать, доступ к общим данным делают взаимно исключающим или атомарным.

Пример использования:

Например, есть общий счетчик заказов, который увеличивается из нескольких потоков. Без защиты можно потерять часть инкрементов, потому что операция count++ не атомарна.

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    private static int _count = 0;
    private static readonly object _lock = new object();

    static void Main()
    {
        Parallel.For(0, 100_000, _ =>
        {
            lock (_lock)
            {
                _count++;
            }
        });

        Console.WriteLine(_count);
    }
}

Пояснение кода:

Код показывает защиту общей переменной _count через lock.
Шаги такие:

  1. Несколько потоков одновременно заходят в Parallel.For.
  2. Каждый поток хочет увеличить общий счетчик.
  3. Внутри lock одновременно может находиться только один поток.
  4. Поэтому операция _count++ выполняется без гонки.
  5. В итоге значение счетчика будет корректным и близким к ожидаемому 100000.

Если убрать lock, часть инкрементов может потеряться, потому что ++ состоит из нескольких шагов: прочитать значение, увеличить, записать обратно.

Ключевые моменты:

  • Проблема называется race condition: результат зависит от порядка выполнения потоков.
  • lock подходит для защиты критической секции и сложных операций над общим состоянием.
  • Interlocked удобен для атомарных простых операций, например инкремента.
  • Неправильная синхронизация может привести не только к неверным данным, но и к deadlock’ам.
  • Чем меньше область блокировки, тем лучше обычно для производительности.
  • Если данные не разделяются между потоками, синхронизация может не понадобиться.