2008년 04월 19일
LeaveCriticalSection 한번만 호출하기
CRITICAL_SECTION 는 한 프로세스내에서의 동기화를 위한 object이다.
http://msdn2.microsoft.com/en-us/library/ms682530.aspx
이미 CRITICAL_SECTION 을 소유한 스레드가 다시 EnterCriticalSection 으로 그것을 소유하려고 하는경우 에러없이 넘어간다.
그러나 한번 LeaveCriticalSection 으로 CRITICAL_SECTION 을 해제한 다음 다시LeaveCriticalSection 을 호출하면, 즉 소유하지 않는 스레드에서 LeaveCriticalSection 을 호출하면 다음번 EnterCriticalSection 호출시에 deadlock 이 발생한다.
이것을 막자면 현재 스레드가 그 Critical section 을 소유하고 있는 경우에만 LeaveCriticalSectin 을 호출하도록 하여야 한다.
아래와 같이 동기화 클래스를 만들면 이 문제를 해결할수 있다.
*** 더 좋은 방법을 알려주시면 감사하겠습니다...
class CSingleCriticalSection
{
public:
CSingleCriticalSection();
~CSingleCriticalSection();
BOOL IsCurrentThreadLocked();
void Lock();
void Unlock();
protected:
CCriticalSection m_section;
DWORD volatile m_dwThreadId;
};
inline CSingleCriticalSection::CSingleCriticalSection()
{
InterlockedExchange((PLONG)&m_dwThreadId, 0);
}
inline CSingleCriticalSection::~CSingleCriticalSection()
{
Unlock();
}
BOOL inline CSingleCriticalSection::IsCurrentThreadLocked()
{
return m_dwThreadId && m_dwThreadId == GetCurrentThreadId();
}
void inline CSingleCriticalSection::Lock()
{
if(!IsCurrentThreadLocked())
{
m_section.Lock();
InterlockedExchange((PLONG)&m_dwThreadId, (LONG)GetCurrentThreadId());
}
}
void inline CSingleCriticalSection::Unlock()
{
if(IsCurrentThreadLocked())
{
m_section.Unlock();
InterlockedExchange((PLONG)&m_dwThreadId, (LONG)0);
}
}
http://msdn2.microsoft.com/en-us/library/ms682530.aspx
이미 CRITICAL_SECTION 을 소유한 스레드가 다시 EnterCriticalSection 으로 그것을 소유하려고 하는경우 에러없이 넘어간다.
그러나 한번 LeaveCriticalSection 으로 CRITICAL_SECTION 을 해제한 다음 다시LeaveCriticalSection 을 호출하면, 즉 소유하지 않는 스레드에서 LeaveCriticalSection 을 호출하면 다음번 EnterCriticalSection 호출시에 deadlock 이 발생한다.
이것을 막자면 현재 스레드가 그 Critical section 을 소유하고 있는 경우에만 LeaveCriticalSectin 을 호출하도록 하여야 한다.
아래와 같이 동기화 클래스를 만들면 이 문제를 해결할수 있다.
*** 더 좋은 방법을 알려주시면 감사하겠습니다...
class CSingleCriticalSection
{
public:
CSingleCriticalSection();
~CSingleCriticalSection();
BOOL IsCurrentThreadLocked();
void Lock();
void Unlock();
protected:
CCriticalSection m_section;
DWORD volatile m_dwThreadId;
};
inline CSingleCriticalSection::CSingleCriticalSection()
{
InterlockedExchange((PLONG)&m_dwThreadId, 0);
}
inline CSingleCriticalSection::~CSingleCriticalSection()
{
Unlock();
}
BOOL inline CSingleCriticalSection::IsCurrentThreadLocked()
{
return m_dwThreadId && m_dwThreadId == GetCurrentThreadId();
}
void inline CSingleCriticalSection::Lock()
{
if(!IsCurrentThreadLocked())
{
m_section.Lock();
InterlockedExchange((PLONG)&m_dwThreadId, (LONG)GetCurrentThreadId());
}
}
void inline CSingleCriticalSection::Unlock()
{
if(IsCurrentThreadLocked())
{
m_section.Unlock();
InterlockedExchange((PLONG)&m_dwThreadId, (LONG)0);
}
}
# by | 2008/04/19 20:12 | 컴퓨터 | 트랙백 | 덧글(1)





☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
아래와 같이 수정한다.
void inline CSingleCriticalSection::Unlock()
{
if(IsCurrentThreadLocked())
{
InterlockedExchange((PLONG)&m_dwThreadId, (LONG)0);
m_section.Unlock();
}
}