Я недавно узнал о шести порядках памяти в С ++, меня очень смущали memory_order_acquire
и memory_order_release
, вот пример из cpp:
#include <thread>
#include <atomic>
#include <cassert>
std::atomic<bool> x = {false};
std::atomic<bool> y = {false};
std::atomic<int> z = {0};
void write_x() { x.store(true, std::memory_order_seq_cst); }
void write_y() { y.store(true, std::memory_order_seq_cst); }
void read_x_then_y() {
while (!x.load(std::memory_order_seq_cst));
if (y.load(std::memory_order_seq_cst))
++z;
}
void read_y_then_x() {
while (!y.load(std::memory_order_seq_cst));
if (x.load(std::memory_order_seq_cst))
++z;
}
int main() {
std::thread a(write_x);
std::thread b(write_y);
std::thread c(read_x_then_y);
std::thread d(read_y_then_x);
a.join(); b.join(); c.join(); d.join();
assert(z.load() != 0); // will never happen
}
На справочной странице cpp говорится:
Этот пример демонстрирует ситуацию, когда необходимо последовательное упорядочивание.
Любой другой порядок может вызвать утверждение, потому что потоки c и d могли бы наблюдать изменения в атомах x и y в противоположном порядке.
Итак, у меня вопрос: почему здесь нельзя использовать memory_order_acquire и memory_order_release? А какую семантику предоставляют memory_order_acquire и memory_order_release?
некоторые ссылки: https://en.cppreference.com/w/cpp/atomic/memory_order https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync