C++支持的原子线程防护,即使用std::atomic<>
函数来保证使用atomic_thread_fence
操作的线程的属性的防护。它需要一个内存顺序参数来调整围栏的“强度”。
我知道,当并非所有原子操作都以“strong”顺序完成时,fence的作用是:
(1)包括RMW操作
因此,所有这些(acquire,release和acq_rel防护)的用途都是显而易见的:它们允许使用原子操作弱于acq/rel的线程(分别)进行适当同步。
但我不知道在哪里特别需要memory_order_seq_cst
作为围栏:memory_order_seq_cst
原子操作和memory_order_seq_cst
栅栏的含义是什么? memory_order_seq_cst
不能保证的memory_order_acq_rel
栅栏(在原子操作的可能排序方面)将具体保证什么?
最佳答案
不,seq-cst-fence不仅是发行版栅栏,而且还是获取-栅栏,而且还提供了一些其他属性(请参阅Working Draft, Standard for Programming Language C++, 32.4.4-32.4.8)。 seq-cst防护也是所有顺序一致的操作的单个总顺序的一部分,强制执行以下观察结果:
memory_order_seq_cst
栅栏X,则B观察到M的最后一个memory_order_seq_cst
修改在X之前以总顺序S或M的后续修改按照其修改顺序。 memory_order_seq_cst
栅栏X,使得A在X和B跟随S中的X之前被排序,则B观察到任一影响A或M的后续修改顺序(按其修改顺序)。 memory_order_seq_cst
栅栏X和Y,使得A在X之前排在X之前,Y在B之前在Y之前排序, S,然后B观察到A的影响或M的后续修改(按其修改顺序)。 例如,我在危险指针实现中使用seq-cst围栏:https://github.com/mpoeter/xenium/blob/master/xenium/reclamation/impl/hazard_pointer.hpp
在存储了危险指针之后,但在重新读取指向该对象的指针之前,获得对某些对象的安全引用的线程使用seq-cst围栏。试图回收某些对象的线程在从所有线程收集事件危害指针之前使用seq-cst防护。根据上述规则,这可以确保尝试回收该对象的线程看到其他某个线程对该对象具有HP(即,使用了该对象),或者确保尝试获取对该对象的安全引用的线程重载返回一个不同的指针,指示该线程该对象已被删除,并且必须执行重试。