c++11 原子排序:锁的扩展总顺序 memory_order_seq_cst

ita*_*taj 5 c++ multithreading atomic c++11

来自 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 不存在,则在相对于 B 的可见副作用序列中对 M 进行某些修改的结果,该序列不是 memory_order_seq_cst。

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

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

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

我已将这个问题发送到 comp.std.c++ 但在那里没有得到答案。http://groups.google.com/group/comp.std.c++/browse_frm/thread/5242fa70d0594d1b#

jpa*_*cek 3

“总是”是什么意思?

始终意味着存在S+l与和seq_cst ops U lock ops一致的全序。happens-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要求。