2013-07-30 2 views
0

잠금 및 디자인에 관한 C++의 책을 읽었습니다. 심판과 같은 문 ++ 사소한 보이지만멀티 스레드에서 싱글 톤 사용

void addRef() { ref++; } 
void subRef() { if(--ref == 0) delete this; } 

, 그것은 원자이다 보장 없습니다. 그러나이 코드를 다시 작성하여 잠금을 추가하기 전에 응용 프로그램에서 잠금을 사용하는 방법을 알아야합니다. 이 에서 subRef 다음에 addRef가 호출되면 버그가 생성됩니다. 문제는 잠금이 누락되지 않았기 때문에 잘못된 디자인입니다. 객체 이 스레드의 범위를 벗어나 지속되어야하는 경우, 범위를 벗어나지 않는 다른 스레드에 의해 생성되고 소유되어야합니다 ( ).

위의 텍스트에 대한 내 질문은 무엇을 저자가 가난한 디자인으로 의미 하는가 방법이 객체가 스레드의 범위를 넘어 지속해야하는 경우 "에 의해 피할 수있다, 그것은 생성하고 소유해야

  1. 입니다 범위를 벗어나지 않는 다른 스레드. " ? 이것에 대한 예를 들어 줄 것을 요청하십시오.
+1

'std :: atomic'도 잘 동작합니다. 하지만 '이것을 삭제하십시오'는 어쨌든 끔찍한 것입니다. 실제로 카운트 된 객체 내의 참조 카운터는 무엇입니까 – nijansen

+1

실제 질문에 상관없이 질문 제목에 싱글 톤을 언급하는 이유는 무엇입니까? –

답변

1
void thread1work(RefCntObj* refcntObj) 
{ 
    refcntObj.addRef(); 
    // any work 
    refcntObj.subRef(); 
} 

int main(void) { 
    RefCntObj* refcntObj= new RefCntObj(); // I assume the constructor calls addRef() 
    std::thread t(thread1work, std::ref(f)); 
    refcntObj->subRef(); // may be called after thread1Work or before it 
} 

수 있도록은 thread1work 메인의 refcntObj->subRef(); 전에 호출된다는 보장이 없다. 이 경우 객체는 이미 삭제되고 포인터는 무효화됩니다.

0

코드 디자인이 좋지 않아서 작성자는 클래스와 메서드를 잘못 작성했다는 것을 의미합니다. 어떤 위치에 코드를 액세스 할 수있게하는지, 어떻게 배치 할 것인가?

"개체가 스레드 범위를 넘어서 유지해야하는 경우 범위를 벗어나지 않는 다른 스레드가 개체를 만들고 소유해야합니다."

간단하게 위의 의미 넣어 당신은 A (나사)의 내부에 B를 가지고 있지만 당신은 당신이 스레드 (A) 내부에서 B를 제거해야보다, 또한 C에서 B를 사용하고부터가 독립 할 필요가있는 경우 당신이 모두에서 사용하고 C.

0

누가 알겠습니까? 저자에게 물어보아야 할 것입니다. 이것은 내게 계산되는 고전적인 참조처럼 보입니다 : 안전을 위해서 사용자에게 모든 액세스를 보호하기위한 뮤텍스를 ref으로 지정하거나 ref을 일종의 원자 변수로 만듭니다. (C++ 11 사용할 수있는 std::atomic<int>에 기능의 전체 범위를 가지고있다.) 인용 된 텍스트에 관해서

: 당신이 바로 그것을 사용하지 않는 경우는 안전하지 않은 아무것도 할 수 있습니다. 두 개의 스레드가 같은 인스턴스에 액세스하는 경우 이 계속 존재하도록 스레드가 참조를 삭제하는 경우 이미 ref이 2 이상이어야합니다. 에 스레드를 추가 할 필요가 없습니다.