Это плохой пример, хотя я полагаю, он иллюстрирует, насколько деформирующими могут быть расслабленные атомы.
[intro.execution]p9:
Каждое вычисление значения и побочный эффект, связанные с полным выражением, упорядочиваются перед каждым вычислением значения и побочным эффектом, связанным со следующим оцениваемым полным выражением.
[атомный порядок]p2:
Атомарная операция A, которая выполняет операцию освобождения атомарного объекта M, синхронизируется с атомарной операцией B, которая выполняет операцию получения M и получает свое значение от любого побочного эффекта в последовательности выпуска, возглавляемой A.
В результате показанные оценки связаны друг с другом последовательностью до и синхронизацией с отношениями:
Thread 1 Thread 2 Thread 3
y.store(20)
|
| s.b.
V s.w.
x.store(10) --------> x.load() == 10
|
| s.b.
V s.w.
y.store(10) --------> y.load() == 10
|
| s.b.
V
x.load() == ?
Таким образом, каждая оценка в цепочке происходит перед следующей (см. [intro.races]стр. 9–10).
[intro.races] p15,
Если вычисление значения A атомарного объекта M происходит до вычисления значения B для M и A берет свое значение из побочного эффекта X на M, тогда значение, вычисленное B, должно быть сохраненным значением на X или значение, сохраненное побочным эффектом Y в M, где Y следует за X< /em> в порядке изменения M.
Здесь A — это нагрузка в потоке 2, которая приняла значение 10, B — это нагрузка в потоке 3 (в утверждении). Поскольку A происходит раньше, чем B, и нет других побочных эффектов на x
, B также должно читаться как 10.
У Херба Саттера есть гораздо более простой пример в его блоге< /а>:
T1: x = 1;
T2: y = 1;
T3: if( x == 1 && y == 0 ) puts("x first");
T4: if( y == 1 && x == 0 ) puts("y first");
Вам абсолютно необходима последовательная согласованность, чтобы гарантировать печать не более одной строки.
person
T.C.
schedule
21.05.2018
relaxed
; он никогда не используетacquire/release
. - person Nicol Bolas   schedule 21.05.2018memory_order_relaxed
иmemory_order_seq_cst
в качестве первых двух атомарных операций. И в разделе режима освобождения/приобретения нет примера, соответствующего этому коду. В нем есть что-то похожее на часть этого кода, но не на весь код. И в разделе конкретно говорится, что утверждение не сработает. Просто найдите y.load(memory_order_acquire) == 10; вы не найдете его на этой странице. - person Nicol Bolas   schedule 21.05.2018