来自c ++ 11 29.3-p3:
所有memory_order_seq_cst操作上应该有一个总订单S,与所有受影响位置的“发生之前”订单和修改订单一致,这样每个从原子对象M加载值的memory_order_seq_cst操作B都会观察到任何一个以下值:
- S中B的最后一次修改A的结果,如果它存在,或
- 如果A存在,则对于B的副作用的可见序列中的M的某些修改的结果不是在memory_order_seq_cst之前且在A之前不发生,或
- 如果A不存在,则对于B的副作用的可见序列中的M的某些修改的结果不是memory_order_seq_cst。
[注意:虽然没有明确要求S包含锁,但它总是可以扩展到包含锁定和解锁操作的顺序,因为它们之间的顺序已经包含在“之前发生”排序中。 - 后注]
在最后一个注释中,“始终”是什么意思? 我可以理解,任何特定的实现都可以设计为支持这样的扩展S.但是在一些不是为它设计的一般实现中,我没有看到S可以用所描述的属性进行扩展。
这是否意味着扩展订单在这里也满足相同的可见性属性?
我已将此问题发送至comp.std.c ++但在那里没有得到答案。 http://groups.google.com/group/comp.std.c++/browse_frm/thread/5242fa70d0594d1b#
答案 0 :(得分:2)
“永远”是什么意思?
始终表示S+l
上的总订单seq_cst ops U lock ops
与happens-before
和S
一致。
事实1:S
是与HB
一致的总订单。
事实2:锁定操作按HB
部分顺序排序,因为它们是获取/释放操作。
事实3:HB
中没有周期。
引理1:S' = S union HB
中没有循环。
证明:如果S'
中有任何循环,它们将采用Aop1 <S Aop2 <HB Aop1
形式,因为任何两个原子操作在S
中具有可比性,并且之前发生的是传递性的。这与事实1相矛盾.QED
结论:因为对于每个部分订单(=没有周期),存在其对总订单的扩展(参见拓扑排序),总订单延伸S'
。所以你只需从中选择原子并锁定操作并得到S+l
。
但是在一些不是为它设计的一般实现中,我没有看到S可以扩展。
此类实施不符合mem_order_seq_cst
要求。