Сбор мусора в книге "С++ Concurrency in Action"
Книга Вильямса оказалась сложнейшей из всех,что я читал. Вопрос у меня по реализации сбора мусора в lock-free stack.
Была проблема удаления нод в структуре, при доступе нескольких потоков к методу pop(). Автор реализует подсчёт количества потоков,которые находятся в методе,и добавляет метод try_reclaim(node* old_head), из-за реализации которого я и решил впервые в жизни задать здесь вопрос.
template<typename T>
class lock_free_stack
{
private:
std::atomic<unsigned> threads_in_pop;
void try_reclaim(node* old_head);
struct node
{
std::shared_ptr<T> data;
node* next;
node(T const& data_):
data(std::make_shared<T>(data_))
{}
};
std::atomic<node*> head;
std::atomic<node*> to_be_deleted;
public:
void push(T const& data)
{
node* const new_node=new node(data);
new_node->next=head.load();
while(!head.compare_exchange_weak(new_node->next,new_node));
}
std::shared_ptr<T> pop()
{
++threads_in_pop;
node* old_head=head.load();
while(old_head &&
!head.compare_exchange_weak(old_head,old_head->next));
std::shared_ptr<T> res;
if(old_head)
{
res.swap(old_head->data);
}
try_reclaim(old_head);
return res;
}
};
void try_reclaim(node* old_head)
{
if(threads_in_pop==1)
{
node* nodes_to_delete=to_be_deleted.exchange(nullptr);
if(!--threads_in_pop)
{
delete_nodes(nodes_to_delete);
}
else if(nodes_to_delete)
{
chain_pending_nodes(nodes_to_delete);
}
}
}
Основной вопрос по проверке на if(threads_in_pop==1) и if(!--threads_in_pop), ведь даже не смотря на то,что эта переменная атомарная, никто не гарантирует,что во время следующего блока кода - она не измениться другим потоком,и вызов метода delete_nodes() станет не безопасным.