2016-10-29 2 views
4

Предположим, что у меня есть 2 темы:переназначения атомарных операций в C++

int value = 0; 
std::atomic<bool> ready = false; 

thread 1: 
value = 1 
ready = true; 

thread 2: 
while (!ready); 
std::cout << value; 

эта программа может выводить 0?

Я прочитал о модели памяти C++ - в частности, последовательная согласованность, которая, по моему мнению, является дефолтом, и это было не особенно ясно. Требуется ли компилятору просто выполнять атомарные операции в правильном порядке относительно друг друга или требуется, чтобы атомарные операции были в правильном порядке относительно всех других операций?

+1

Это немного сложнее, чем это: есть * в потоке * и * между потоками *, чтобы рассмотреть. В принципе, правила работают «как ожидалось», чтобы код был правильным и делает то, что вы думаете, что он должен делать. –

+2

Для последовательной согласованности это очень похоже на барьер; вещи над ним не могут быть перегруппированы, чтобы идти дальше, а вещи ниже не могут быть перегруппированы, чтобы идти до него. Не имеет значения, являются ли другие значения атомарными или нет. В этом случае вы в порядке. – ShadowRanger

ответ

2

По умолчанию операции над атомными переменными выполняются с использованием семантики memory_order_seq_cst, которая гарантирует, что переупорядочение не будет выполнено.

Таким образом, линия: value = 1 не может быть заказана ниже атомном назначение: value = 1, поэтому линии std::cout << value; всегда будет печатать 1.

по тем же правилам, линия: std::cout << value; не может быть заказана
выше линии: while (!ready);.

1

Он действует как барьер памяти, как и ответ ShadowRanger. Однако, для более подробной информации о том, почему это так, я предлагаю посмотреть на Herb Sutter's talk on atomic weapons. Он подробно разбирается в том, как и почему атомистика работает.

Смежные вопросы