2010-01-29 6 views
4

boost :: weak_ptr을 사용하여 아무도 객체 중 하나를 사용하지 않을 때 얻을 수있는 객체 풀을 구현할 생각입니다. 내 관심사는 멀티 스레드 환경이기 때문에 범위를 벗어나는 개체에 대한 마지막 shared_ptr과 weak_ptr에서 생성 된 새로운 shared_ptr 사이에 경쟁 조건이있는 것으로 보입니다. 일반적으로 잠금 또는 무언가로 이러한 작업을 보호 할 수 있습니다. 그러나 여기서 중요한 것은 shared_ptr이 언제 범위를 벗어날 지 모를 때입니다.리소스 풀을 구현하는 다중 스레드 프로그램에서 weak_ptr을 향상 시키십시오.

나는 boost :: shared_ptr 및 boost :: weak_ptr에 대해 오해하고 있습니까? 그렇지 않다면 누구에게 무엇을해야하는지에 대한 좋은 제안이 있습니까?

감사합니다. 앤드류

답변

9

는 정상적으로와 shared_ptr를 구성하여 강한 참조를 잡아해야하는 weak_ptr 사용하십시오. 이 마지막 단계는 원 자성입니다. 강한 참조를 다시 얻거나 bad_weak_ptr 예외가 발생합니다. (또는, weak_ptrlock()를 호출하고, 강한 참조 또는 null를 얻을 중 하나.)

예 (lock()으로, 다른 스타일에 적응하기 쉬운 충분히) :

void do_something(weak_ptr<foo> weak) { 
    // Grab strong reference 
    shared_ptr<foo> strong(weak.lock()); 
    if (strong) { 
     // We now have a strong reference to use 
    } else { 
     // No strong references left; object already freed 
    } 
} 
+3

week_ptr이 삭제 된 객체를 가리키는 경우 생성자가 bad_weak_ptr 예외를 throw하기 때문에 shared_ptr이 유효한지 여부를 테스트 할 필요가 없다고 생각합니다. 또는 weak_ptr :: lock()을 사용해야합니다. throw하지 않지만 NULL을 가리키는 shared_ptr을 반환 할 수 있습니다. – Serge

+1

그래서 원자가? man 페이지의 Thread Safety 섹션은 내 마음 속에 의심의 여지를 남겨 둡니다. –

+0

@ Serge : 고마워요! 나는 내 직책을 고치겠다. –

0

예, 틱. 포인터에 액세스하는 측면에서 Boost는 모든 것을 안전하게 만들어야합니다. 그것은 그들의 요점의 일부입니다.

그러나 마지막 shared_ptr이 꺼질 때까지 기다렸다가 다음 포인터를 만들 때까지 지연이 예상되는 경우 널 포인터가 표시됩니다. (적절하게 점검하고 있다면, 당신은 appropro fail case를 가져야한다.)

그러나 안전 스레드 오는 경우는

3
모두 boost::weak_ptr

boost::shared_ptr이 유사 잘못된 shared_ptr을 끝낼 수 없습니다 객체 어딘가에 파괴 될 것입니다 위험이있는 경우 그들은 스레드로부터 안전하지 않습니다 . boost::shared_ptr 또는 weak_ptr에서 참조 된 개체가 어딘가에서 영구적으로 참조되는 경우 아무런 위험없이 shared/weak ptrs를 사용할 수 있습니다.

그러나 일부 작업이 개체의 마지막 생활 인스턴스 역 참조에가는 경우, 그 시간에 당신이 weak_ptr에 대한 몇 가지 작업을 수행 할 수 없습니다 특히 : 내부적 shared_ptr를 사용하기 때문에 다른 weak_ptrweak_ptr를 할당 할 수 없습니다. 또한 결과가 정의되지 않았으므로 잠금을 사용할 수 없습니다. 또한 expired() 메서드는 쓸모가 없습니다.이 메서드는 true를 반환 할 수 있지만 코드의 다음 줄은 개체가 이미 만료되었을 수 있습니다.

관련 문제