C++0x并发同步,是需要的fence
我最近问了一些有关原子和 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);
}
我是否正确地读到原子存储释放/加载获取序列是一个与显式栅栏版本具有相同内存顺序含义的同步事件?也就是说,第二个版本正确吗?
如果正确,那么第二个发出的栅栏就超出了必要的范围:即使当 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);
}
I've recently asked a few questions about atomics and C++0x, and I'd like to ensure I understand the ordering semantics before I convert any code. Let's say we have this pre-0x code:
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);
}
Using whatever your current compiler/platform offers you for atomic_int
, atomic_store_fence
and atomic_load_fence
.
In C++0x the code has a few possible forms. Two obvious ones appear to be:
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);
}
or
Thread A:
b = something;
a.store( 1, memory_order_release );
Thread B:
if( a.load( memory_order_acquire ) == 1)
{
proc(b);
}
Am I correct in reading that an atomic store-release / load-acquire sequence is a synchronizes-with event that has the same memory order implications as the explicit fence version? That is, is the second version correct?
If correct then the second one issues the fence more than necessary: even when a != 1
. Section 29.8-3 of the standard indicates I can mix and match atomics and fences. So is the below then a correct and reasonable implementation?
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,您的理解是正确的,是的,最终的列表是一个合理的实现。
请注意,
ATOMIC_VAR_INIT
主要是为了与 C1X 兼容而提供的,在 C++0x 中你可以直接编写:Yes, your understanding is correct, and yes the final listing is a reasonable implementation.
Note that
ATOMIC_VAR_INIT
is primarily provided for compatibility with C1X, in C++0x you can just write: