Str*_*ger 6 stack lock-free c++11
我正在阅读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));
}
};
Run Code Online (Sandbox Code Playgroud)
关键是在接口中compare_exchange_weak,在这种情况下需要2个参数.第一个是对期望值的引用,第二个是期望值.如果原子的当前值不等于预期输入,则它将返回false并将预期输入设置为当前值.
所以在这种情况下,它正在做的是设置new_node->next = head.然后,它说是否head仍然相等new_node->next,交换成head.如果它不再是该值,则使用引用new_node->next为其分配当前值head.由于失败的循环的每次迭代也替换new_node->next为当前值head,因此没有读取在循环体中复制它.