Я запутался в многопоточном программировании и надеялся, что кто-то может прийти и похлопывать меня каким-то пониманием.
Проделав довольно много чтения, я пришел к пониманию, что могу установить значение 64-битного int атомарно в 64-битной системе 1.
Я нашел много этого чтения трудным, хотя, поэтому подумал, что я попытаюсь сделать тест, чтобы проверить это. Поэтому я написал простую программу с одним потоком, который установил бы переменную в одно из двух значений:
bool switcher = false;
while(true)
{
if (switcher)
foo = a;
else
foo = b;
switcher = !switcher;
}
И еще один поток, который будет проверять значение foo
:
while (true)
{
__uint64_t blah = foo;
if ((blah != a) && (blah != b))
{
cout << "Not atomic! " << blah << endl;
}
}
Я установил a = 1844674407370955161;
и b = 1144644202170355111;
. Я запускаю эту программу и не получаю никаких предупреждений о том, что blah
не a
или b
.
Отлично, похоже, что это, вероятно, атомная запись... но затем я изменил первый поток, чтобы установить a
и b
напрямую, например:
bool switcher = false;
while(true)
{
if (switcher)
foo = 1844674407370955161;
else
foo = 1144644202170355111;
switcher = !switcher;
}
Я снова запустил и вдруг:
Not atomic! 1144644203261303193
Not atomic! 1844674406280007079
Not atomic! 1144644203261303193
Not atomic! 1844674406280007079
Что изменилось? В любом случае я назначаю большое число foo
- компилятор обрабатывает постоянное число по-другому или я все неправильно понял?
Спасибо!
<ч/" > 1: Документация Intel CPU, раздел 8.1, Гарантированные Atomic Operations