3

我最近问了一些关于原子和 C++0x 的问题,我想确保在转换任何代码之前了解排序语义。假设我们有这个 pre-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_int,atomic_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);
}

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

如果正确,则第二个问题超出必要的范围:即使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);
}
4

1 回答 1

5

是的,您的理解是正确的,是的,最终的清单是一个合理的实现。

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

std::atomic<int> a(0);
于 2011-04-09T20:24:12.997 回答