Задать вопрос
@Acaunt

Могут ли возникнуть проблемы при одновременном чтении и записи в разных потоках переменной?

Вот абстрактный пример:
#include <iostream>
#include <thread>

int main() {
    size_t i = 0;
    
    std::thread th(
        [&i]() {
            while (i++ < 1'000'000'000'000);
        }
    );
    
    for (size_t j = i; j < 1'000'000'000'000; j = i) {
        if (j % 2) std::cout << j << '\n';
    }
    
    th.join();
    
    return 0;
}


Один поток что-то делает с переменной, другой только считывает. Других потоков больше нет. Что может произойти при данной гонке данных?

Вопрос больше косается простых типов, чем сложных классов.

И да я знаю про std::atomic, это больше философский вопрос, что может произойти? Просто, как мне кажется ничего страшного произойти не должно.
  • Вопрос задан
  • 82 просмотра
Подписаться 1 Простой 1 комментарий
Решения вопроса 1
@rPman
без использования синхронизации стандарт говорит что будет неопределенное состояние.

Например, оптимизация может разместить переменную в регистре, и пока поток/контекст не закончится, реально ее в памяти не менять, т.е. соседний поток будет считывать начальное состояние.

А еще есть кеши процессора, переупорядочивание инструкций или к примеру простой цикл может быть размножен на несколько операций (например четыре повторения но цикл уменьшится в 4 раза), если это будет эффективнее для процессора, и соответственно реально записывать переменную только на каждый шаг цикла, ну а соседний поток будет считывать значение только по по каждому шагу цикла

Ну и конечно же, внезапно, может все работать как ожидается, без глюков.

p.s. если size_t не укладывается в битность текущей архитектуры, например будет занимать два слова вместо одного, то и записывать в память будет неатамарным способом, и возможна ситуация, когда соседний поток считывает число из двух половинок, одну с одной итерации цикла, а другую с другой, получив что то типа 0000 9999 -> 0001 0000 число 0000 0000
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Ничего страшного не произойдет, да. Просто вы никак не проконтролируете, когда запись из первого потока будет видна во втором потоке. Например, вы тут можете увидеть скачек сразу на 2, или несколько раз подряд одно и то же значение, хоть оно по идее должно постоянно и монотонно расти.
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
Сильно зависит от того, что такое size_t, но на распространённых платформах, где size_t совпадает с разрядностью машины, может или расти скачками, или вообще висеть в одном состоянии.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы