http://en.cppreference.com/w/cpp/atomic/memory_order и другие онлайн-ссылки С++ 11, определите memory_order_acquire и memory_order_release как:
- Операция получения: no reads в текущем потоке может быть переупорядочена перед этой загрузкой.
- Операция Release: no write в текущем потоке может быть изменена после этого хранилища.
Это, по-видимому, позволяет выполнять операции post-purchase-write до операции получения, что кажется мне странным тоже (обычная семантика операции получения/выпуска ограничивает перемещение all операции с памятью).
Тот же источник в Интернете (http://en.cppreference.com/w/cpp/atomic/atomic_flag) предполагает, что мьютексы спин-спина могут быть построены с использованием атомарности С++ и вышеупомянутых правил упорядочения свободной памяти:
lock mutex: while (lock.test_and_set(std::memory_order_acquire))
unlock mutex: lock.clear(std::memory_order_release);
С этим определением блокировки/разблокировки не будет нарушен простой код ниже, если memory_order_acquire/release действительно определены таким образом (т.е. не запрещает переупорядочение пост-приобретать-пишет):
Thread1:
(0) lock
(1) x = 1;
(2) if (x != 1) PANIC
(3) unlock
Thread2:
(4) lock
(5) x = 0;
(6) unlock
Возможно ли следующее выполнение: (0) lock, (1) x = 1, (5) x = 0, (2) PANIC? Что я пропустил?