В примере boost::atomic
, unref
функция:
void intrusive_ptr_release(const X * x)
{
if (x->refcount_.fetch_sub(1, boost::memory_order_release) == 1) {
boost::atomic_thread_fence(boost::memory_order_acquire);
delete x;
}
}
1: операция fetch_sub ограничена memory_order_release, что предотвращает переупорядочение предыдущих операций после точки. Но каковы возможные сцены, которые будут иметь такое явление?
2: в дополнение к memory_order_release на атомной опера, почему есть дополнительный memory_order_acquire до удаления?
По первому вопросу, это предотвращает любое использование (*x)
быть переупорядочен после fetch_sub
(когда счетчик ссылок может быть 0 и использование, следовательно, запрещено). Возможные причины — переупорядочение процессора или перекомпиляция компилятора. Второй вопрос — просто зеркало выпуска; Выпуск защищает магазины и приобретает защищает грузы.
Может показаться, что refcount_fetch_sub(1, memory_order_acq_rel)
работает также, но это защищает только refcount.