В вашем коде, как для load
, так и для store
, порядок между забором и атомной операцией должен быть отменен, а затем аналогичен автономным операциям, но есть различия.
Операции по получению и освобождению от атомных переменных действуют как односторонние барьеры, но в противоположных направлениях. То есть, магазина/выпуск операции предотвращает операцию памяти, которые предшествуют его (в исходной программе) от быть заказаны после него, в то время как нагрузки/приобретает операция предотвращает операцию памяти, которые следуют его от заказано перед ним.
// thread 1
// shared memory operations A
a.store(5, std::memory_order_release);
x = 42; // regular int
// thread 2
while (a.load(std::memory_order_acquire) != 5);
// shared memory operations B
операции памяти A не может двигаться вниз ниже store/release
, в то время как операции с памятью В не может перемещаться вверх над load/acquire
. Как только поток 2 считывает 5, операция памяти A видна для B, и синхронизация завершена.
Будучи односторонним барьером, запись в x
может соединяться или даже предшествует операциям памяти A, но поскольку она не является частью отношения получения/освобождения, x
не может быть надежно доступ к потоку 2.
Замена атомарных операций с автономными резьбовыми ограждениями и расслабленными операциями аналогично:
// thread 1
// shared memory operations A
std::atomic_thread_fence(memory_order_release);
a.store(5, std::memory_order_relaxed);
// thread 2
while (a.load(std::memory_order_relaxed) != 5);
std::atomic_thread_fence(memory_order_acquire);
// shared memory operations B
Это дает тот же результат, но важное различие состоит в том, что оба заборы не выступают в качестве односторонних барьеров; Если бы это произошло, атомный магазин до a
мог быть переупорядочен до освобождения, а атомная нагрузка от a
может быть переупорядочена после захвата забора и , что нарушит соотношение синхронизации.
В целом:
- Автономный выпуск забор предотвращает предшествующие операции от быть заказаны с (атомными) магазинами, которые следуют за ним.
- Автономный захват забора предотвращает переупорядочение следующих операций с (атомными) нагрузками, которые предшествуют ему.
Стандарт позволяет смешивать заготовки/выпускные ограждения с операциями Acquire/Release.
Неуправляемые атомные доступа обеспечивают сигнальные заборы, а также резьбовые заборы?
Это не совсем понятно мне, что вы спрашиваете здесь, потому что нить заборы, как правило, используются с расслабленными атомарных операций, но std::thread_signal_fence
похож на std::atomic_thread_fence
, за исключением того, что он должен работать в том же потоке и поэтому компилятор не генерирует инструкции ЦП для межпоточной синхронизации. Он в основном выступает только как компилятор.