#cpp #многопоточность #atomic
У нас есть 2 потока, которые асинхронно записывают в переменную tmp числа 322 и 1337. Странность в том, что даже если переменная atomic, условие все-таки иногда срабатывает (причем даже намного чаще, чем если бы переменная было просто int), но в cout все-таки вводится либо 1337 или 322. Объясните пожалуйста как все-таки защитить переменную от считывания во время записи. Казалось бы что на 32битных системах все переменные до 4 байт должны записываться атомарно. Вот код: #include "pch.h" #include#include #include using namespace std; int main() { setlocale(LC_ALL,"rus"); atomic tmp = 322; thread th0([&tmp]() { for (int i = 0; i < 100000000; i++) { tmp = 322; this_thread::sleep_for(chrono::microseconds(2)); } }); thread th1([&tmp]() { for (int i = 0; i < 100000000; i++) { tmp = 1337; this_thread::sleep_for(chrono::microseconds(3)); } }); for (int i = 0; i < 10000000; i++) { if(tmp!=322&&tmp!=1337)cout << "Ошибка =" < Ответы
Ответ 1
Все тут атомарно (естественно, кроме вычисления всего выражения в if). А чего вы ожидали? Объявив tmp atomic вы заставили компилятор обращаться к памяти при каждом упоминании tmp. Соответственно, в if(tmp!=322&&tmp!=1337) значение tmp будет выбираться дважды. Если первое чтение вернуло 1337, а второе 322, то выполнится cout << "Ошибка =" <Ответ 2
Операции tmp!=322 и tmp!=1337 не атомарны, так как std::atomic не имеет функций operator!=, и даже если бы имел то операция && между ними точно не атомарнаОтвет 3
Проблема в том, что пока происходит проверка на условие, переменная иногда успевает менять свое значение. Для того чтобы избежать такой проблемы, нужно сохранить во временную переменную значение переменной перед началом проверки for (int i = 0; i < 10000000; i++) { int ntmp = tmp; if(ntmp !=322&& ntmp !=1337)cout << "Ошибка =" <
Комментариев нет:
Отправить комментарий