在C++ Concurrency in Action一书中,作者给出了一个使用危险指针实现无锁堆栈数据结构的例子。部分代码如下:
std::shared_ptr<T> pop()
{
std::atomic<void*>& hp=get_hazard_pointer_for_current_thread();
node* old_head=head.load();
node* temp;
do
{
temp=old_head;
hp.store(old_head);
old_head=head.load();
} while(old_head!=temp);
// ...
}
描述说
您必须在
while
循环中执行此操作,以确保在读取旧指针和设置危险指针node
之间没有删除。head
在此窗口期间,没有其他线程知道您正在访问此特定节点。head
幸运的是,如果要删除旧 节点,head
它本身肯定已经改变,因此您可以检查这一点并继续循环,直到您知道head
指针仍然具有您设置危险指针的相同值。
我认为代码有缺陷,因为head
节点受ABA 问题的影响。即使 的值head
保持不变,它最初指向的节点也可能已被删除。分配了一个新head
节点,该节点恰好与前一个节点具有相同的地址值。