Причины просты: ваши заборы ничего не делают и в любом случае не могут здесь быть полезными, потому что нет записи, что забор сделал бы видимым (на стороне выпуска) сторону получения .
Простой ответ заключается в том, что поток чтения может запускаться первым и, очевидно, не увидит никакой записи, если он это сделает.
Более длинный ответ: , когда ваш код имеет расу ,как любой код, который использует мьютексы или атомики нетривиальным образом, он должен быть подготовлен к любому результату гонки! Поэтому вы должны убедиться, что не чтение значения, записанного записью, не нарушит ваш код.
ДОПОЛНИТЕЛЬНОЕ ОБЪЯСНЕНИЕ
Способ объяснить семантику rel / ack таков:
- release означает « Я достиг чего-то », и яустановите для этого атомарного объекта какое-то значение, чтобы опубликовать это утверждение;
- приобретает означает " вы что-то сделали? ", и я прочитал этот атомарный объект, чтобы увидеть, содержит ли онм.
Поэтому выпуск до того, как вы что-то сделали, не имеет смысла, а приобретение, которое выбрасывает информацию, содержащую претензию, как в (void)x.load(memory_order_acquire)
, как правило, бессмысленно, так как нет знаний (в целом) очто было приобретено, то есть о том, что было достигнуто.(Исключением из этого правила является ситуация, когда у потока были ослабленные загрузки или операции RMW.)