我最近问了一些关于原子和 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_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);
}
我是否正确地阅读了原子存储释放/加载获取序列是一个同步事件,它与显式围栏版本具有相同的内存顺序含义?也就是说,第二个版本是否正确?
如果正确,则第二个问题超出必要的范围:即使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);
}