new_node-> compare_exchange_weak中的下一次更新

时间:2016-06-01 13:33:31

标签: c++ c++11

http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange

template<typename T>
class stack
{
    std::atomic<node<T>*> head;
 public:
    void push(const T& data)
    {
      node<T>* new_node = new node<T>(data);

      // put the current value of head into new_node->next
      new_node->next = head.load(std::memory_order_relaxed);

      // now make new_node the new head, but if the head
      // is no longer what's stored in new_node->next
      // (some other thread must have inserted a node just now)
      // then put that new head into new_node->next and try again
      while(!head.compare_exchange_weak(new_node->next, new_node,
                                        std::memory_order_release,
                                        std::memory_order_relaxed))
          ; // the body of the loop is empty
    }
};

如果有另一个插入新节点的线程,我很难理解new_node->next如何自动指向新头。对于更通用的情况,变量head不是单个链表,compare_exchange_weak在这种情况下如何工作?

1 个答案:

答案 0 :(得分:1)

表达式head.compare_exchange_weak(new_node->next, new_node)执行的原子操作大致相当于:

if (head == new_node->next) {
    head = new_node;
    return true;
}
else {
    new_node->next = head;
    return false;
}

因此,如果没有其他线程调用push()head将等同于new_node->next,因此我们将head更新为指向new_node。如果某个其他线程调用push(),则比较将失败,因此我们更新new_node->next以指向现在的新head并重复直到我们成功。