C ++ 11锁定自由堆栈

时间:2014-06-30 15:36:12

标签: c++11 stack lock-free

我正在阅读Anthony Williams的 C ++ Concurrency in Action ,并且不理解push类的lock_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)); 
 }
};

2 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:3)

来自compare_exchange_weak的文档:

  

以原子方式将* this中存储的值与值进行比较   预期,如果这些是平等的,则取代前者   (执行读 - 修改 - 写操作)。否则,加载实际   存储在* this中的值到期望值(执行加载操作)。

如您所见,否则head的实际值加载到预期中。