考虑以下代码:
struct payload
{
std::atomic< int > value;
};
std::atomic< payload* > pointer( nullptr );
void thread_a()
{
payload* p = new payload();
p->value.store( 10, std::memory_order_relaxed );
std::atomic_thread_fence( std::memory_order_release );
pointer.store( p, std::memory_order_relaxed );
}
void thread_b()
{
payload* p = pointer.load( std::memory_order_consume );
if ( p )
{
printf( "%d\n", p->value.load( std::memory_order_relaxed ) );
}
}
C++ 是否对线程 a 中的栅栏与线程 b 中的消费操作的交互做出任何保证?
我知道在这个例子中我可以用 store-release 替换栅栏 + atomic store 并让它工作。但我的问题是关于使用围栏的这种特殊情况。
阅读标准文本,我可以找到关于释放栅栏与获取栅栏的交互以及释放栅栏与获取操作的交互的条款,但没有关于释放栅栏和消费操作的交互的条款。
我认为,用获取替换消耗将使代码符合标准。但据我了解处理器实现的内存排序约束,我应该只需要线程 b 中较弱的“消耗”排序,因为内存屏障强制线程 a 中的所有存储在存储到指针之前可见,并且读取有效负载取决于从指针读取。
标准一致吗?