Одновременное увеличение общей переменной двумя потоками с задержкой

В программе есть гонка данных: два потока несинхронизированно изменяют обычный int. Поведение неопределено, поэтому нельзя гарантировать ни 200000, ни какой-либо диапазон значений.

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

Что ответить на собеседовании

В программе есть гонка данных: два потока несинхронизированно изменяют обычный int. Поведение неопределено, поэтому нельзя гарантировать ни 200000, ни какой-либо диапазон значений.

Подробный разбор

Ответ с пояснениями

Условие

В программе объявлена глобальная переменная counter1. Два потока создаются, каждый из них перед началом работы ждёт две секунды, а затем выполняет 100 000 инкрементов counter1. После завершения обоих потоков значение counter1 выводится на экран.

static int counter1;

void run()
{
    auto threadFunc = []()
    {
        using namespace std::chrono_literals;
        std::this_thread::sleep_for(2000ms);
        for (int i = 0; i < 100000; i++)
        {
            ++counter1;
        }
    };

    std::thread th(threadFunc), th2(threadFunc);
    th.join();
    th2.join();
    std::cout << counter1 << std::endl;
}

Ответ

В программе есть гонка данных: два потока несинхронизированно изменяют обычный int. Поведение неопределено, поэтому нельзя гарантировать ни 200000, ни какой-либо диапазон значений.

Задержка sleep_for не упорядочивает инкременты. join позволяет дождаться завершения потоков, но не устраняет конфликт между ними во время работы.

Для независимого счётчика объявите std::atomic<int> counter1{0}; и выполняйте counter1.fetch_add(1, std::memory_order_relaxed). После обоих join результат единственного запуска будет 200000. Если счётчик связан с другими общими данными, потребуется дополнительно продумать их синхронизацию.

Источник: eel.is.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее