2017-04-26 7 views
-1

앤서니 윌리엄스의 액션 북에서의 동시성 (Concurrency)에서, 그는 split reference count를 사용하여 lock free 스택을 구현합니다. 머리 노드의 초기로드 후. 그는 아래 코드에 나열된 메소드 호출 increase_head_count를 사용합니다.액션 북의 동시성에서 분리 된 참조 카운트를 사용하여 잠금없는 스택 구현

counted_node_ptr old_head = head.load(); 
increase_head_count(old_head); 

void increase_head_count(counted_node_ptr& old_counter) 
{ 
    counted_node_ptr new_counter; 

    do 
    { 
     new_counter = old_counter; 
     ++new_counter.external_count; 
    } 
    while (!head.compare_exchange_strong(old_counter, new_counter)); 

    old_counter.external_count = new_counter.external_count; 
} 

이 링크 https://github.com/subjam/concurrency-in-action/blob/master/ch7/stack_ref.cpp에서 전체 구현을 찾을 수 있습니다.

내 질문은, 하나 이상의 스레드가 동시에 pop()을 실행하려고 시도하고 모든 스레드가 헤드 노드를 읽은 다음 하나만 종료 될 때까지 실행되고 이후에이 구현이 어떻게 작동하는지 다른 질문이 실행되면 발생합니다.

저는 꽤 오랫동안 여기에 갇혀 있습니다. 누군가 이해하면 도와 주시면 정말 기뻐하실 것입니다.

답변

1

while 절에서 old_counter가 여전히 new_counter와 같으면 head가 new_counter로 설정됩니다. 한 번에 성공하는 단일 스레드의 경우입니다.

이 메서드에 동시에 액세스하는 다른 스레드의 경우 compare_exchange_strong()은 루프 반복을 유발하는 false를 반환합니다. 그러나 old_counter의 내용에 대해 머리글을 복사합니다.

이것은 다른 (실패한) 스레드에 대한 다음 루프에서 old_counter가 head의 현재 내용으로 업데이트되었음을 ​​의미합니다.

+0

답장을 보내 주셔서 감사합니다.이 질문에 대한 의구심을 가지십시오. 견인 스레드가 increase_head_count 함수를 실행하고 하나가 처음에 일시 중지되었습니다. 이제 한 스레드는 모든 방법을 실행하고 old_node 포인터도 삭제합니다 (링크에서 제공된 전체 구현 참조). 일시 중지 된 스레드가 깨어 났을 때 예외가 발생하지 않습니다 (잘못된 메모리 또는) ++ new_counter.external_count를 실행할 때; 코드는 삭제 된 노드를 참조하므로 (첫 번째 스레드에 의해) – Kasun

+0

첫 번째 스레드 ('increase_head_count()'메서드를 통해)는 삭제하기 전에'head'를 제어합니다. 삭제하기 전에 스택에서 제거하려고 시도합니다. 스택에서 성공적으로 제거되면 두 번째 스레드 ('increase_head_count()'에서 깨어나게됩니다)는 head에 대한 참조를 갖지 않습니다. 위에서 말한 것처럼'old_counter'는 새로운'head'를 가리 키도록 업데이트 될 것이므로 삭제 된 노드에 액세스하려고하지 않을 것입니다. –

+0

이 코드에 대한 나의 관심은 첫 번째 (성공한) 스레드가 마지막으로 푸시 된 노드에 대한 제어권을 얻고 'head'가 이제 원래의 'counted_node_ptr'을 가리키면이 두 번째 스레드의 코드 (메소드'pop') 'ptr'는'NULL'이므로이'head'를 삭제하려고 시도하지 않습니다. 헤드를 삭제하지 않으면'counted_node_ptr' 안에서 반복되는 모든 2 차 스레드가'pop'을 떠나서'T'의 빈 값을 반환합니다. 그러나'head'의 원래 값에 대한'ptr'는 생성자 없이는 초기화되지 않기 때문에'NULL'이되는 것은 아닙니다. –