Да, есть проблема: это не гарантирует работу в C ++. Но это очень просто исправить, если вы используете хотя бы C ++ 11: используйте вместо этого std::atomic<bool>
, например:
#include <atomic>
std::atomic<bool> Global_Stop = false;
void do_stuff() {
while (!Global_Stop) {
//...
}
}
Одна проблема заключается в том, что компилятору разрешено переупорядочивать обращения к памяти, если он может доказать, что это не изменит эффект программы:
int foo() {
int i = 1;
int j = 2;
++i;
++j;
return i + j;
}
Здесь компилятору разрешено увеличивать j
перед i
, потому что это явно не изменит эффект программы. Фактически, он может оптимизировать все это до return 5;
. Итак, что считается «не изменит эффекта программы»? Ответ длинный и сложный, и я не претендую на то, чтобы понять их все, но одна его часть заключается в том, что компилятор должен беспокоиться только о потоках в определенных контекстах. Если бы i
и j
были глобальными переменными вместо локальных, он все равно мог бы поменять местами ++i
и ++j
, потому что разрешено предположить, что к ним обращается только один поток , если вы не используете определенные примитивы потока (например, mutex
).
Теперь, когда дело доходит до такого кода:
while (!Global_Stop) {
//...
}
Если он может доказать, что код, скрытый в комментарии, не касается Global_Stop
, и нет примитивов потоков, таких как мьютекс, он может с радостью оптимизировать его до:
if (!Global_Stop) {
while (true) {
//...
}
}
Если он сможет доказать, что Global_Stop
равен false
в начале, он может даже удалить if
проверьте!
На самом деле дела обстоят еще хуже, по крайней мере теоретически. Видите ли, если поток находится в процессе записи в переменную, когда другой поток обращается к нему, тогда может наблюдаться только часть этой записи, что дает вам совершенно другое значение (например, вы обновляете i
с 3
до 4
а другой поток читает 7
). По общему признанию, это маловероятно с bool
. Но стандарт еще шире, чем этот: это неопределенное поведение , поэтому он может даже sh взломать вашу программу или иметь какое-то другое странное неожиданное поведение.