2009-12-15 4 views
9

부스트 :: 뮤텍스 목적으로 lock/unlock을 해제하지 않았으므로 내 메시지의 제목이 도발적으로 보일 수도 있습니다. 잠금 장치).boost :: mutex/뮤텍스가 잠겨 있는지 테스트하는 방법

그러나 부스트 설명서는 이러한 측면에서 매우 짧기 때문에 (다음 내용은 아무리 줄 잡아도) 다음 사용 사례에서 나를 도울 수있는 사람이 있는지 묻습니다.

는이 클래스 푸, 있다고 가정 :
-
완료하는 데 약간의 시간이 소요 소멸자 - 별개의 스레드에 의해 호출되는 방법을하지만, 파괴시 호출 할 수 없습니다

class Foo 
{ 
public: 

    virtual ~Foo() 
    { 
    //Time consuming operations here 
    } 


    //Method called by a timer belonging to a distinct class 
    void OnTimer() 
    { 
    //Other time consuming stuff. Should not be called during destruction ! 
    } 


}; 

나는 부스트를 기반으로 버전 :: 뮤텍스

//boost::mutex implementation 
class Foo 
{ 
public: 
    Foo() 
    { 
    } 

    virtual ~Foo() 
    { 
    { 
     boost::mutex::scoped_lock lock(mDisposingMutex); 
     //Time consuming operations here 
    } 
    } 


    //Method called by a timer belonging to a distinct class 
    void OnTimer() 
    { 
    { 
     //Imaginary code here: mutex::locked() method is private !!! 
     if (! mDisposingMutex.locked()) 
     return; 
    }  
    //Other time consuming stuff. Should not be called during destruction ! 
    } 

private: 
    boost::mutex mDisposingMutex; 
}; 

오전 내가 완전히 잘못을 구현하기 위해 (성공하지) 시도? 아무도 boost :: mutex를 어떻게 처리해야하는지 알려 줄 수 있습니까?

감사합니다. 당신이 소멸자 본문에 Lockable::lock()를 사용하여 커밋 경우

+0

가 왜 객체가 파괴되고 이제 아래의 코드가 제대로 컴파일? –

+0

질문에 직접 대답하지 않으면 소멸자의 첫 번째 단계로 'OnTimer()'호출을 유발하는 등록을 취소 할 수 있습니까? 물론, 호출은 여전히 ​​"동시에"비동기 적으로 발생할 수 있습니다. 그러나 파괴가 진행되는이 객체가 여전히 이러한 콜백의 대상인 이유는 명확하지 않습니다. – seh

+0

@Anon : 동의합니다. 이것은 코드 냄새입니다. 나는 아직도 대답에 관심이있다. @Seh : 귀하의 의견은 동일한 코드 냄새를 기반으로합니다. 그러나 캡슐화를 위반하지 않고 직접 취소 할 수는 없습니다. –

답변

5

, 당신은 당신의 OnTimer() 기능을 사용 Lockable::try_lock()을 가지고 있고, 그 함수가 true를 돌려주는 경우에만 진행할 수 있습니다. OnTimer()이 먼저 시작하면 OnTimer()이 소멸자를 넣습니다. 그러나 은 여전히 ​​이며 뮤텍스를 실행하고 완료하고 해제하는 소멸자 문제를 해결하지 못했습니다. OnTimer() 뮤텍스를 시작하고 성공적으로 잡는 것입니다.

이러한 시퀀스는 정의되지 않은 동작 영역에있을 가능성이 있지만 저주가 발생하지 않도록합니다. 뮤텍스 이외에 상태 플래그 을 사용하면 위의 사례에서 설명한 것과 유사합니다.이 후자의 경우를 감지하고 플래그를 읽는 것 이외의 작업을 수행하지 않게 할 수 있습니다 (OnTimer()). 그러나 어떤 점에서는 Band-Aids를 Band-Aids 위에 놓기 만하면됩니다.

2

뮤텍스 :: try_lock는()

+0

뮤텍스를 잠근 사람은 false를 반환합니다. –

4

@Seh : 전적으로이 코드 냄새에 동의하고 근본 원인을 수정해야합니다.

그러나 나와 동일한 문제 (즉, 부스트 의사와의 싸움)를 겪고있는 사람을 돕기 위해 나는 제안을 구현하려고 시도했습니다. (코드 냄새 지금은 매우 강력하지만) 다른 스레드가 여전히에 대한 포인터를 가지고있는 동안

#include <boost/thread/mutex.hpp> 

//boost::mutex implementation 
class Foo 
{ 
public: 
    Foo() : 
    mIsDisposing(false) 
    { 
    } 

    virtual ~Foo() 
    { 
    { 
     boost::try_mutex::scoped_try_lock lock(mDisposingMutex); 
     if (! lock.locked()) 
     { 
     //Die by horrible death, or wait before trying again... 
     } 
     else 
     { 
     mIsDisposing = true; 
     } 
     //Time consuming operations here 
    } 

    } 


    //Method called by a timer belonging to a distinct class 
    void OnTimer() 
    { 
    { 
     boost::try_mutex::scoped_try_lock lock(mDisposingMutex); 
     if (! lock.locked() || mIsDisposing) 
     { 
     return;  
     } 
    }  
    //Other time consuming stuff. Should not be called during destruction ! 
    } 

private: 
    boost::try_mutex mDisposingMutex; 
    bool mIsDisposing; 
}; 
관련 문제