3

来自 c++11 29.3-p3:

在所有 memory_order_seq_cst 操作上应有一个总顺序 S,与所有受影响位置的“发生在”顺序和修改顺序一致,以便从原子对象 M 加载值的每个 memory_order_seq_cst 操作 B 观察以下任一价值观:

-- 在 S 中 B 之前的 M 的最后修改 A 的结果,如果它存在,或者

-- 如果 A 存在,则在与 B 相关的可见副作用序列中 M 的某些修改的结果不是 memory_order_seq_cst 并且不会在 A 之前发生,或者

-- 如果 A 不存在,M 在可见的副作用序列中对 B 的一些修改的结果,它不是 memory_order_seq_cst。

[ 注意:虽然没有明确要求 S 包含锁,但它总是可以扩展到包含锁定和解锁操作的顺序,因为它们之间的顺序已经包含在“发生在”顺序中。--结束注]

在最后一个注释中,“总是”是什么意思?我可以理解任何特定的实现都可以设计为支持这样的扩展 S。但是在一些不是为它设计的通用实现中,我看不到 S 可以使用所描述的属性进行扩展。

这是否意味着在这里也满足相同可见性属性的扩展顺序?

我已将此问题发送到 comp.std.c++,但没有得到任何答案。http://groups.google.com/group/comp.std.c++/browse_frm/thread/5242fa70d0594d1b#

4

1 回答 1

2

“总是”是什么意思?

总是意味着存在一个与和S+l一致的全序。seq_cst ops U lock opshappens-beforeS

这是为什么

事实 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要求。

于 2012-06-03T10:38:31.977 回答