2009-03-19 4 views
4

저는 C++로 32 멀티 스레딩을 위해 노력하고 있습니다. 시나리오 : 여러 스레드에서 사용하는 함수가 있습니다. 이 섹션은 중요한 섹션 (또는 리소스를 잠글 수있는 모든 종류의 구조)으로 작동합니다. 중요 섹션에서 예외가 발생합니다. 이 시점에서 예외 catch 블록에서 리소스의 잠금을 해제해야합니다.중요한 섹션에서 던져진 예외를 잡는 방법?

다른 방법으로이 작업을 수행 할 수 있습니까? 내 말은, catch 블록에서 잠금을 해제하는 것을 기억하고 싶지는 않다고 가정 해 봅시다.이 오류가 발생하기 쉬운 시나리오를 피하기 위해이 문제를 처리하는 일반적인 방법이 있습니까?

답변

16

아이디어는 객체를 구성하는 것이 CS를 획득하고 객체를 파괴하여 객체를 해제하는 것과 같이 객체의 중요 섹션을 획득하고 해제하는 동작을 캡슐화하는 것입니다.

struct CSHolder { 
    explicit CSHolder(CRITICAL_SECTION& cs): lock(cs) { 
     ::EnterCriticalSection(&lock); 
    } 
    ~CSHolder() { ::LeaveCriticalSection(&lock); } 
    CRITICAL_SECTION& lock; 
}; 


CRITICAL_SECTION gLock; 
void foo() { 
    CSHolder lockIt(gLock); 
    // lock is held until lockIt is destroyed 
} 

개념은 RAII입니다. - 자원 획득은 초기화입니다. 현대 C++에서 매우 일반적인 관용구입니다.

2

중요한 섹션을 생성자 매개 변수로 사용하는 대괄호 클래스를 작성합니다. 생성자에서 EnterCriticalSection을 호출하고 소멸자에서 LeaveCriticalSection을 호출합니다. C++ 예외가 발생하면 스택 해제는 나머지 작업을 수행합니다.

+0

이것은 boost :: mutex :: lock 객체의 동작입니다. – greyfade

+0

scoped_lock 오히려. – greyfade

2

MFC를 사용할 수 있다면 CSingleLock을 사용하면됩니다. 다음과 같이 사용할 수 있습니다 :

void f() 
{ 
    try 
    { 
    CSingleLock lock(&m_criticalSection, TRUE); 

    } 
    catch(/*some exception*/) 
} 

잠금 장치는 소멸자의 중요한 섹션의 잠금을 해제합니다. lock은 예외가 발생했을 때 로컬 객체이므로 스택이 unwind되고 잠금 객체 소멸자가 실행되어 중요한 섹션을 잠금 해제합니다.

3

기존 프레임 워크를 사용하는 경우 이미이 작업을 수행 할 수있는 RAII 컨테이너 클래스가있을 수 있습니다. MFC를 사용하는 경우 CSingleLock을 살펴보고 부스트 모양을 scoped_lock으로 사용하고 있습니다.

모든 사람이 자신의 것을 굴려 야한다고 생각하는 (또는 생각해야하는 것) 수치입니다.

+0

동의합니다 ... 사람들이 아직도 boost :: mutex 나 비슷한 것을 사용하는 대신에 CRITICAL_SECTION을 직접 사용하는 것은 부끄러운 일입니다. 어쩌면 정답은 네이티브 CS보다 boostable Lockable 개념을 구현하는 어댑터를 작성하는 것입니다. 흠 ... –

관련 문제