2012-03-24 5 views
1

멀티 스레드 환경에서 "작동"하는 샘플 코드는 멀티 스레드 코드에서 shared_ptr 사용

void CSampleClass::Stop(void) { 
    if (m_pDB != nullptr) { 
    ... Here is some code 
    m_pDB->Interrupt(); 
    } 
}
입니다. 여기서 m_pDB 구성원은 boost::shared_ptr<CSampleDatabase> m_pDB;으로 선언됩니다. m_pDB은 다른 클래스 메소드에서 재설정 될 수 있습니다. 그것이 nullptr이 아닌 것으로 테스트 된 이유입니다. 코드에 여러 스레드가 있으므로 m_pDBif (...)m_pDB->Interrupt(); 사이의 다른 스레드가 다시 설정하면 상황이 일 수 있습니다. 결과는 아주 극적입니다. 이러한 상황을 방지하기 위해 다음 코드 수정
void CSampleClass::Stop(void) { 
    auto pDb = m_pDB; //lock 
    if (pDb != nullptr) { 
    ... Here is some code 
    pDb->Interrupt(); 
    } 
}
을 사용합니다. 즉 m_pDB.reset();이 호출되면 pDb이 삭제 될 때까지 객체가 해제되지 않습니다.

질문은 다음과 같습니다

  1. 등 로커, 뮤텍스, 중요한 부분을 포함하지 않고 상황을 방지하기 위해 "표준"방법이 있나요? boost::weak_ptr을 사용하여 순환 참조를 중단하는 것과 같은 것입니다.

  2. 컴파일러에서 pDBboost::shared_ptr<CSampleDatabase>으로 지정하고 CSampleDatabase *을 지정하지 않았습니까? decltype(m_pDB) pDb = m_pDB; //lock을 쓰는 것이 더 안전 할 수 있습니까?

+2

두 번째 버전에는 여전히 경쟁 조건이 있습니다. 'shared_ptr'을 복사 생성하는 것은 원 자성 연산이 아닙니다. – Mankarse

+0

@ Mancarse : 인용? –

+0

@nm : [여기] (http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm#ThreadSafety)에서 : "shared_ptr 개체는 기본 제공되는 것과 동일한 수준의 스레드 안전성을 제공합니다 유형 ". 이것은 동일한 객체를 참조하는 복수의'shared_ptr' 인스턴스를 동시에 가지는 것이 안전하고 동시에'shared_ptr' 인스턴스를 수정/읽기하는 것은 안전하지 않다는 것을 의미합니다. – Mankarse

답변

2

제시된 해결책은 안전하지 않습니다. 그것은 the documentation에서이 예제와 유사합니다

// thread A 
p = p3; // reads p3, writes p 

// thread B 
p3.reset(); // writes p3; undefined, simultaneous read/write 

동시는 안전 동일한 인스턴스에서를 읽습니다. 동일한 인스턴스에 대한 다른 동시 조작은 그렇지 않습니다.

사물함, 뮤텍스, 중요 섹션 등을 포함하지 않고 상황을 방지하는 "표준"방법이 있습니까? boost :: weak_ptr을 사용하여 순환 참조를 끊는 것과 같은 것입니다.

상호 배제가 필요하므로 상호 제외 구성을 사용해야합니다.

는 컴파일러가 boost::shared_ptr<CSampleDatabase>pDB하지 CSampleDatabase * 선언 보장되어 있습니까? decltype(m_pDB) pDb = m_pDB; //lock을 쓰는 것이 더 안전 할 수 있습니까?

예, pDBshared_ptr입니다.