- в какой ситуации Assert(z.load() != 0); потерпит неудачу.
почему использование Memory_order_seq_cst вместо Memory_order_ack_rel приводит к тому, что z никогда не становится равным 0.
Код: Выделить всё
#include
#include
#include
std::atomic x = {false};
std::atomic y = {false};
std::atomic 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
}
- и y = false
Код: Выделить всё
x = true
- и y = true
Код: Выделить всё
x = false
- и y = true
Код: Выделить всё
x = true
- и y = false
Код: Выделить всё
x = false
Этот пример демонстрирует ситуацию, когда необходимо последовательное упорядочение. Любой другой порядок может вызвать утверждение, поскольку потоки c и d смогут наблюдать изменения атомов x и y в противоположном порядке.
Я не понимаю, как это возможно. Как изменения x и y будут происходить в противоположном порядке?
Кроме того, мне интересно, как использование Memory_order_seq_cst решит проблему. Это заставляет x.load в read_x_then_y выполняться до y.load?
Подробнее здесь: https://stackoverflow.com/questions/764 ... otal-order