围栏的例子

上面的例子也可以用栅栏和松散的原子操作来实现:

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;
  }
}

如果原子加载操作看到原子存储写入的值,则存储在加载之前发生,并且栅栏也是如此:释放栅栏发生在获取栅栏之前,对释放栅栏之前的 xy 的写入变为可见获取围栏之后的 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 标志在放松原子载荷的帮助下设置。然后使用单个获取围栅来提供所需的内存排序。