C++ 11锁定自由堆栈

Str*_*ger 6 stack lock-free c++11

我正在阅读Anthony Williams的C++ Concurrency in Action,并且不了解它pushlock_free_stack类实现.

为什么原子load不在while循环中呢?他给出的理由是:

因此,您不必每次都通过循环重新加载头,因为编译器会为您执行此操作.

但我不明白.有人可以对此有所了解吗?

template<typename T>
class lock_free_stack
{
private:
 struct node
 {
   T data;
   node* next;
   node(T const& data_) : 
     data(data_)
   {}
 };
 std::atomic<node*> head;
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)); 
 }
};
Run Code Online (Sandbox Code Playgroud)

Dav*_*e S 6

关键是在接口中compare_exchange_weak,在这种情况下需要2个参数.第一个是对期望值的引用,第二个是期望值.如果原子的当前值不等于预期输入,则它将返回false并将预期输入设置为当前值.

所以在这种情况下,它正在做的是设置new_node->next = head.然后,它说是否head仍然相等new_node->next,交换成head.如果它不再是该值,则使用引用new_node->next为其分配当前值head.由于失败的循环的每次迭代也替换new_node->next为当前值head,因此没有读取在循环体中复制它.