在Anthony williams的Concurrency in action book中,他使用拆分引用计数实现了无锁堆栈。在头节点初始加载之后。他使用下面代码中列出的方法调用increase_head_count。
counted_node_ptr old_head = head.load();
increase_head_count(old_head);
void increase_head_count(counted_node_ptr& old_counter)
{
counted_node_ptr new_counter;
do
{
new_counter = old_counter;
++new_counter.external_count;
}
while (!head.compare_exchange_strong(old_counter, new_counter));
old_counter.external_count = new_counter.external_count;
}
完整实施可在此链接https://github.com/subjam/concurrency-in-action/blob/master/ch7/stack_ref.cpp中找到。
我的问题是,如果一个senario发生多个线程尝试同时执行pop()并且所有线程都读取头节点然后只有一个执行直到结束而其他线程开始执行此功能之后该实现如何工作。
我被困在这里已经有一段时间了,如果有人能帮助我理解这一点,我会很高兴的。
答案 0 :(得分:1)
如果在while子句中,old_counter仍等于new_counter,则head设置为new_counter。对于任何一次成功的单线程都是这种情况。
对于同时访问此方法的其他线程,compare_exchange_strong()返回false,从而导致循环迭代。但是,它也会复制old_counter的内容。
这意味着在这些其他(不成功)线程的下一个循环中,old_counter已使用head的当前内容进行更新。