Смешение расслабленных и отборных заказов на память - PullRequest
0 голосов
/ 01 февраля 2019

Рассмотрим std::atomic<int> x(0).Если я правильно понимаю, std::memory_order_relaxed гарантирует только то, что операция происходит атомарно, но не дает никаких гарантий синхронизации.Таким образом, x.fetch_add(1, std::memory_order_relaxed) 1000 раз из 2 потоков будет иметь конечный результат 2000 всегда.Однако возвращаемое значение любого из этих вызовов не гарантирует истинного текущего значения (например, 2000-е приращение может вернуть 1700 в качестве предыдущего значения).

Но - и вот мое замешательство - учитывая, что этиприращения происходят параллельно, что вернет x.load(std::memory_order_acquire)?Или x.fetch_add(1, std::memory_order_acq_rel)?Возвращают ли они истинное текущее значение или имеют ту же проблему устаревших ответов, что и ослабленный порядок из-за ослабленных приращений?

Насколько я могу судить, стандарт гарантирует только выпускк приобретению (по той же переменной) синхронизируется и, таким образом, дает истинное текущее значение.Итак, как можно смешать смягченную с типичной семантикой получения-выпуска?

Например, я слышал, что счетчик ссылок std::shared_ptr увеличивается в расслабленном порядке и уменьшается в порядке acq_rel, потому что он должен гарантировать, что он имеетистинное значение, чтобы удалить объект только один раз.Из-за этого у меня возникает соблазн думать, что они дадут истинную текущую стоимость, но я не могу найти какой-либо стандарт, подтверждающий это.

...