围栏的例子
上面的例子也可以用栅栏和松散的原子操作来实现:
int x, y;
std::atomic<bool> ready{false};
void init()
{
x = 2;
y = 3;
atomic_thread_fence(std::memory_order_release);
ready.store(true, std::memory_order_relaxed);
}
void use()
{
if (ready.load(std::memory_order_relaxed))
{
atomic_thread_fence(std::memory_order_acquire);
std::cout << x + y;
}
}
如果原子加载操作看到原子存储写入的值,则存储在加载之前发生,并且栅栏也是如此:释放栅栏发生在获取栅栏之前,对释放栅栏之前的 x
和 y
的写入变为可见获取围栏之后的 std::cout
声明。
如果栅栏可以减少获取,释放或其他同步操作的总数,则栅栏可能是有益的。例如:
void block_and_use()
{
while (!ready.load(std::memory_order_relaxed))
;
atomic_thread_fence(std::memory_order_acquire);
std::cout << x + y;
}
block_and_use()
函数旋转,直到 ready
标志在放松原子载荷的帮助下设置。然后使用单个获取围栅来提供所需的内存排序。