Вы испытываете неопределенное поведение.
Ваш код имеет состояние гонки;один поток читает a
, в то время как другой пишет, и синхронизация не происходит.Вам не разрешено делать это в C ++.Программы, которые делают это, могут быть скомпилированы так, чтобы делать что угодно .
На самом деле, при сборке релиза, я ожидаю, что компиляция до if(false)
.Компилятор оптимизирует основной поток, не замечает никакой синхронизации, доказывает, что a не может иметь 3 различных значения без UB, и оптимизирует if
.
В отладочной сборке я мог ожидать появления симптомов, которые вы видите.Не потому, что это более правильно, а потому, что отладочные сборки, как правило, не допускают такого неопределенного поведения.
Итак, первое, что вы должны сделать, чтобы разумно рассказать о своей программе, это удалить неопределенное поведение: make a
a std::atomic<int>
вместо int
.
Теперь и в выпуске, и в отладке вы ожидаете увидеть ... именно то, что показал ваш тест.Или ничего.Или что-нибудь промежуточное.Результат больше не является неопределенным, но он остается недетерминированным.
Оператор if
не является атомарным.Между условиями a
может изменить .И с программой, выполняющейся вечно, это может происходить иногда, так как другой поток меняет ее. Даже гарантии прогресса вперед в порядке, потому что вы читаете атомарную переменную.