我最近问过几个关于原子和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_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);
}
或
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);
}
答案 0 :(得分:5)
是的,您的理解是正确的,是的,最终列表是合理的实施。
请注意,ATOMIC_VAR_INIT
主要是为了与C1X兼容而提供的,在C ++ 0x中你可以写:
std::atomic<int> a(0);