Я прочитал следующую статью Антони Уильямса, и, как я понял в дополнение к общему количеству атомов в std::shared_ptr
в std::experimental::atomic_shared_ptr
, фактический указатель на общий объект также является атомарным?
Но когда я прочитал ссылку на подсчитанную версию lock_free_stack
, описанную в книге Антония о С++ Concurrency, мне кажется, что те же самые апплики также для std::shared_ptr
, потому что функции, подобные std::atomic_load
, std::atomic_compare_exchnage_weak
, применяются к экземплярам std::shared_ptr
.
template <class T>
class lock_free_stack
{
public:
void push(const T& data)
{
const std::shared_ptr<node> new_node = std::make_shared<node>(data);
new_node->next = std::atomic_load(&head_);
while (!std::atomic_compare_exchange_weak(&head_, &new_node->next, new_node));
}
std::shared_ptr<T> pop()
{
std::shared_ptr<node> old_head = std::atomic_load(&head_);
while(old_head &&
!std::atomic_compare_exchange_weak(&head_, &old_head, old_head->next));
return old_head ? old_head->data : std::shared_ptr<T>();
}
private:
struct node
{
std::shared_ptr<T> data;
std::shared_ptr<node> next;
node(const T& data_) : data(std::make_shared<T>(data_)) {}
};
private:
std::shared_ptr<node> head_;
};
Какова точная разница между этими двумя типами интеллектуальных указателей, и если указатель в экземпляре std::shared_ptr
не является атомарным, то почему это возможно в случае реализации стека блокировки без блокировки?