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

时间:2011-04-09 17:35:27

标签: c++ c++11 atomic memory-fences

我最近问过几个关于原子和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);
}

使用您当前的编译器/平台为atomic_intatomic_store_fenceatomic_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);
}

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

Thread B:
if( a.load( memory_order_acquire ) == 1)
{
  proc(b);
}

我是否正确阅读原子商店发布/加载获取序列是同步 - 事件,其具有与显式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);
}

1 个答案:

答案 0 :(得分:5)

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

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

std::atomic<int> a(0);