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
在这种情况下如何工作?
答案 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
并重复直到我们成功。