Почему разные потоки могут видеть разные порядки операций с памятью? [дубликат]C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Почему разные потоки могут видеть разные порядки операций с памятью? [дубликат]

Сообщение Anonymous »

Следующий код представляет собой пример из книги C++ Concurrency в действии (2-е издание). Автор упоминает, что потоки Ta и Tb могут наблюдать разные состояния памяти:
  • Ta наблюдает x == true и y == false.
  • Tb отмечает x == false и y == true.
В результате значение z может быть равно 0.

В результате значение z может быть равно 0.

р>

Код: Выделить всё

std::atomic x(false),y(false);
std::atomic z(0);
void write_x() { // Ta
x.store(true, std::memory_order_release); // A
}
void write_y() { // Tb
y.store(true, std::memory_order_release);  // B
}
void read_x_then_y() { // Tc
while(!x.load(std::memory_order_acquire)); // C
if(y.load(std::memory_order_acquire))      // D
++z;
}
void read_y_then_x() { // Td
while(!y.load(std::memory_order_acquire)); // E
if(x.load(std::memory_order_acquire))      // F
++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);
}
Вот как я понимаю:
Операторы A и B независимы друг от друга, поэтому они могут выполняться в любом порядке. В конкретном исполнении программы будет определенный порядок, например AB или BA. Например, предположим, что порядок равен AB:
  • Когда поток Tc достигает D, x == true, но y все равно может быть ложным, поэтому ++z не будет выполнен.
  • Когда поток Td достигнет F, y == true. Поскольку B выполняется после A, x уже должно быть истинным, поэтому будет выполнено ++z, в результате чего z > 0.
Почему я неправильно понимаю?
Изначально я подозревал, что результат std::atomic::store может не быть сразу виден другим потокам. Например, даже если A выполнился, Td все равно может увидеть x == false, предотвращая выполнение ++z. Однако, исследовав видимость атомарных операций, я обнаружил, что если x.store запускается до x.load, то x.load должен видеть результат x.store, как описано в этом вопросе о Memory_order_relaxed и видимости.
Так почему же Ta и Tb могут наблюдать разные состояния?

Подробнее здесь: https://stackoverflow.com/questions/792 ... ion-orders
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»