Вступить в клуб →
лёгкаявопросLinux, многопоточность и сеть

Два потока увеличивают счётчик, итог меньше ожидаемого

long counter = 0;

void worker() {
    for (int i = 0; i < 1000000; ++i)
        ++counter;
}

Запускаются два потока, оба выполняют worker, затем оба присоединяются через join и печатается counter. Ожидали 2000000, получают разные значения: 1370455, 1682311, изредка ровно 2000000.

Почему так происходит?

  • Потоки не успевают завершить свои циклы до печати результата, поэтому в счётчике оказывается неполная сумма
  • Инкремент не атомарен: чтение, увеличение и запись перемешиваются между потоками, часть увеличений теряется
  • Компилятор развернул цикл и выбросил часть итераций как избыточные, потому что результат нигде не проверяется
  • Достаточно объявить counter как volatile: этот квалификатор делает операцию инкремента атомарной

🔒 Проверка ответа — для участников клуба

  • Проверка ответа
  • Подсказка, если застряли
  • Разбор с объяснением, почему так
  • Прогресс по всем задачам и виртуальные собеседования
Зарегистрироваться →

Регистрация занимает минуту

Другие задачи раздела