Учитывая фрагмент кода c ++:
int a = 0;
atomic<int> b{0};
Thread 1
a = 1;
b.store(1,memory_order_release);
Thread 2
while(!b.load(memory_order_acquire));
assert(a==1);
Мы знаем, что утверждение никогда не срабатывает.
С другой стороны, golang atomic.Store использует инструкцию xchg, котораясоздает барьер памяти, поэтому он может привести к семантике memory_order_release как c ++ 11.
//go:noescape
func Store(ptr *uint32, val uint32)
TEXT runtime∕internal∕atomic·Store(SB), NOSPLIT, $0-12
MOVQ ptr+0(FP), BX
MOVL val+8(FP), AX
XCHGL AX, 0(BX)
RET
Однако реализация atomic.Load - это чистый код go, который означает просто команду mov при сборке.
//go:nosplit
//go:noinline
func Load(ptr *uint32) uint32 {
return *ptr
}
Итак, golang atomic.Load имеет семантику захвата?
Если сделать так, как это работает, и если нет, то как обеспечить упорядочение памяти или сделать видимым a = 1?