Атомарные операции с одной переменной

Каковы возможные окончательные результаты для переменной xв следующем фрагменте кода C++? (ответьте, исходя из того, что разрешено стандартом C++, а не того, что в настоящее время доступно на разных платформах)

// Inside Thread 0
std::atomic<int> x = {2};
// Inside Thread 1
x.fetch_sub(1,std::memory_order_relaxed)
// Inside Thread 2
x.fetch_sub(1,std::memory_order_relaxed)

В идеале хочу xбыть нулем в конце. Так ли это, хотя я используюstd::memory_order_relaxed?

Изменить: чтобы сделать вопрос более точным, гарантируется ли, что 1) в потоках 1 и 2 возвращаемое значение равно 0 или 1, и 2) возвращаемое значение в потоках 1 и 2 отличается.

1 ответ

Решение

Краткий ответ: да.

Длинный ответ: std::memory_order_relaxed описывается как:

Упрощенная операция: нет ограничений на синхронизацию или упорядочение, накладываемых на другие операции чтения или записи, гарантируется только атомарность этой операции.

Источник

Фактически это означает, что он гарантирует только атомарность. Это означает, чтоstd::atomic::fetch_subоперация гарантирует только атомарную операцию чтения-изменения-записи, без какого-либо упорядочивания в отношении других операций. Это, однако, не означает, что компилятор может переупорядочить две разные атомарные операции чтения, изменения и записи (что может привести к гонке данных, что является неопределенным поведением). Они все еще атомарны.

В идеале хочу xбыть нулем в конце. Так ли это, хотя я используюstd::memory_order_relaxed?

Порядок памяти в этом случае не имеет значения. Ни один из них не помешает основным гарантиям атомарности. Сделанное вами выше утверждение будет справедливо для любого порядка памяти, потому что оно по определению истинно для любой атомарной переменной, которая изменяется таким образом (два, потенциально асинхронных, вычитания из начального значения2).

Чтобы сделать вопрос более точным, гарантируется ли, что 1) В обоих потоках возвращаемое значение либо 0 или 1и 2) Возвращаемое значение в потоках 1 а также 2 разные.

Да и да, если потоки возвращают значение, котороеx держится сразу после fetch_subвызов, который, вероятно, технически неверен (потоки не возвращают значения), но я вижу, откуда вы идете.

Другие вопросы по тегам