На некоторых форумах и в книгах (т.е. C ++ Параллелизм в действии) есть хороший пример многопользовательского / многопользовательского стека, и в поп Реализации они обычно делают следующее:
// head is an std::atomic<node*> variable
node *old_head = head.load();
while(old_head && !head.compare_exchange_weak(old_head, old_head->next));
...
Зачем использовать станд :: атомное<T>:: compare_exchange_ * предотвратить проблему ABA?
Скажем так:
Тогда возникнет проблема, связанная с ABA.
Я верю, что что-то упустил. Что мне здесь не хватает?
ура
Да, вы бы страдали от проблемы с ABA здесь.
Хотя я думаю, что это не имеет значения, потому что реализация, на которую вы ссылаетесь (листинг 7.3 в CiA), в любом случае недопустима, это утечка узлов.
Если мы посмотрим на самую простую реализацию с подсчетом ссылок, используемую без блокировки std::shared_ptr
(перечисляя 7.9 в CiA) мы видим, что проблема не возникнет. При использовании общих указателей old_head не будет удален, так как наш поток по-прежнему содержит ссылку на него, так как такой недавно созданный заголовок не может быть создан в адресе памяти старого заголовка.
Есть также ветка на официальном Параллелизм в действии Мэннинг форумов о проблемах ABA в реализации стека.
Других решений пока нет …