C++ 0x并发同步,是需要的围栏

edA*_*a-y 3 c++ atomic memory-fences c++11

我最近问了几个关于原子和C++ 0x的问题,我想确保在转换任何代码之前理解排序语义.假设我们有这个前0x代码:

atomic_int a = 0;
some_struct b;

Thread A:
b = something;
atomic_store_fence();
a = 1;

Thread B:
if( a == 1 )
{
  atomic_load_fence();
  proc(b);
}
Run Code Online (Sandbox Code Playgroud)

使用您当前的编译器/平台为您提供的任何内容atomic_int,atomic_store_fence以及atomic_load_fence.

在C++ 0x中,代码有几种可能的形式.两个显而易见的似乎是:

atomic<int> a = ATOMIC_VAR_INIT(0);
some_struct b;

Thread A:
b = something;
atomic_thread_fence( memory_order_release );
a.store( 1, memory_order_relaxed );

Thread B:
if( a.load( memory_order_relaxed ) == 1)
{
  atomic_thread_fence( memory_order_acquire );
  proc(b);
}
Run Code Online (Sandbox Code Playgroud)

要么

Thread A:
b = something;
a.store( 1, memory_order_release );

Thread B:
if( a.load( memory_order_acquire ) == 1)
{
  proc(b);
}
Run Code Online (Sandbox Code Playgroud)

我是否正确读取原子存储释放/加载获取序列是一个同步事件,它具有与显式fence版本相同的内存顺序含义?也就是说,第二个版本是否正确?

如果正确的话,那么第二个就会发布超过必要的围栏:即使是a != 1.标准的第29.8-3节表明我可以混合和匹配原子和栅栏.那么下面是正确合理的实施吗?

Thread A:
b = something;
a.store( 1, memory_order_release );

Thread B:
if( a.load( memory_order_relaxed ) == 1 )
{
  atomic_thread_fence( memory_order_acquire );
  proc(b);
}
Run Code Online (Sandbox Code Playgroud)

Ant*_*ams 5

是的,您的理解是正确的,是的,最终列表是合理的实施.

注意,ATOMIC_VAR_INIT主要是为了与C1X兼容,在C++ 0x中你可以写:

std::atomic<int> a(0);
Run Code Online (Sandbox Code Playgroud)