Этот вопрос конкретно касается тривиально разрушаемых типов в указателях с подсчетом ссылок. См. Пример из документации Boost об использовании атомных компонентов.
Уменьшение выглядит следующим образом:
if (x->refcount_.fetch_sub(1, boost::memory_order_release) == 1) {
// A
boost::atomic_thread_fence(boost::memory_order_acquire);
delete x;
}
Мы знаем, что из-заmemory_order_release
, все операции чтения / записи x
завершаются до fetch_sub
(см. здесь ). Таким образом, если мы достигнем точки A
, тогда все варианты использования x
будут завершены.
В точке A
в коде мы не гарантируем, что стандартсмотрите последнее значение x
до тех пор, пока memory_order_acquire
ограда ...
Итак, вот мой вопрос относительно второго утверждения о memory_order_acquire
:
Если x
указывает на тривиально разрушаемый тип (например, int
, где x
равен int * const
), то memory_order_acquire
бессмысленно? Я имею в виду, что если x
является тривиально разрушаемым, то последние изменения в x
не влияют на удаление x
?
Например, видит ли поток удаления delete x;
последнийx
такое, что *x = 10
или устаревшее значение, такое, что *x = 8
процесс уничтожения всегда одинаков независимо (до тех пор, пока сам указатель x
остается постоянным). Он знает, что никто не собирается изменять x
с этого момента благодаря выпуску, и поэтому все, что он должен сделать, это освободить.
Есть ли еще одно преимущество memory_order_acquire
, которое я здесь упускаю? Правильно ли мое мышление, и если нет, то почему мы должны видеть последнее значение x
в цепочке удаления?