2016-06-01 2 views
0

http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchangenew_node-> 다음 업데이트는

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은 어떻게 작동합니까? 그래서 우리는 대신 new_node를 가리 키도록 head를 업데이트 다른 스레드가 push()을 호출되지 않은 경우

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

그래서, headnew_node->next 동등 비교합니다 :

답변

1

표현 head.compare_exchange_weak(new_node->next, new_node)은 거의 비슷하다 원자 작업을 수행합니다. 다른 스레드가 push()을 호출 한 경우 비교가 실패하므로 new_node->next을 업데이트하여 이제는 새로운 head을 가리키고 성공할 때까지 반복합니다.