我正在阅读 Anthony Williams Concurrency 的 C++11 书籍。
我对无锁堆栈的弹出实现有点困惑。
template<typename T>
class lock_free_stack
{
private:
struct node
{
std::shared_ptr<T> data;
node* next;
node(T const& data_): data( std::make_shared<T>(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));
}
std::shared_ptr<T> pop()
{
node* old_head = head.load();
while( old_head && !head.compare_exchange_weak(old_head, old_head->next));
// Does This not return the data of the next node before the head if
// compare_exchange_weak returns true
return old_head ? old_head->data : std::shared_ptr<T>();
}
};
让我感到困惑的那一行是 pop 函数的最后两行。
while( old_head && !head.compare_exchange_weak(old_head, old_head->next));
return old_head ? old_head->data : std::shared_ptr<T>();
如果 compare_exchange_weak 函数返回 true,它不会将 old_head 更改为堆栈中的下一个节点吗?当 old_head 不是 nullptr 时,这将导致 return 语句从下一个节点而不是堆栈顶部的旧头返回数据。
我是否错误地解释了这一点?