멀티 스레드 환경에서 "작동"하는 샘플 코드는 멀티 스레드 코드에서 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_pDB
을
if (...)
과
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
이 삭제 될 때까지 객체가 해제되지 않습니다.
질문은 다음과 같습니다
등 로커, 뮤텍스, 중요한 부분을 포함하지 않고 상황을 방지하기 위해 "표준"방법이 있나요?
boost::weak_ptr
을 사용하여 순환 참조를 중단하는 것과 같은 것입니다.컴파일러에서
pDB
을boost::shared_ptr<CSampleDatabase>
으로 지정하고CSampleDatabase *
을 지정하지 않았습니까?decltype(m_pDB) pDb = m_pDB; //lock
을 쓰는 것이 더 안전 할 수 있습니까?
두 번째 버전에는 여전히 경쟁 조건이 있습니다. 'shared_ptr'을 복사 생성하는 것은 원 자성 연산이 아닙니다. – Mankarse
@ Mancarse : 인용? –
@nm : [여기] (http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm#ThreadSafety)에서 : "shared_ptr 개체는 기본 제공되는 것과 동일한 수준의 스레드 안전성을 제공합니다 유형 ". 이것은 동일한 객체를 참조하는 복수의'shared_ptr' 인스턴스를 동시에 가지는 것이 안전하고 동시에'shared_ptr' 인스턴스를 수정/읽기하는 것은 안전하지 않다는 것을 의미합니다. – Mankarse