#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_release);
}
void write_y()
{
y.store(true, std::memory_order_release);
}
void read_x_then_y()
{
while (!x.load(std::memory_order_acquire))
;
if (y.load(std::memory_order_acquire)) {
++z;
}
}
void read_y_then_x()
{
while (!y.load(std::memory_order_acquire))
;
if (x.load(std::memory_order_acquire)) {
++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);
}
Если я заменю seq_cst на получение/выпуск в последнем примере cppreference, может ли assert(z.load() != 0)
быть потерпеть неудачу ?
- Seq_CST может предотвратить переупорядочивание StoreLoad, но код этого не делает.
- Acquire может предотвратить изменение порядка LoadLoad.
- Выпуск может предотвратить повторный заказ StoreStore.