http://goo.gl/GZWI4
http://blog.naver.com/ccw3435/100055320847
//*******************************************************************
//
// FILE: CriticalSectionBase.h
//
// AUTHOR: - TTF(zone0000@dreamwiz.com)
//
// PROJECT: CriticalSection
//
// COMPONENT: CCriticalSectionBase
//
// DATE: 16.05.2007
//
// COMMENTS: - v1.0 (2007.05.16)
// Spin Count를 적용하여 윈도우 버전에 맞게 자동 선택
// try/catch문을 이용하여 동기화 객체 할당시 메모리 오류 assert 처리
//
//*******************************************************************
#pragma once
#include <assert.h>
// 스핀 카운트란? 싱글 Processor 시스템에서는 무시되는 항목이지만,
// 멀티 Processor 시스템에서 Critical Section을 사용할 수 없을 때
// 세마포어와 연계되어 작동하는데, 세마포어는 커널 모드에서 작동하므로
// 호출되는 스레드가 유저모드에서 대기(busy-waiting) 상태로 남아 있을 경우에
// 더욱 효율적일 수 있다.
// 요약 - 유저모드로 대기하는 스레드의 갯수에 대한 설정이다.
class CCriticalSectionBase
{
public:
#if (_WIN32_WINNT < 0x0403)
CCriticalSectionBase()
{
__try
{
InitializeCriticalSection( &m_CS );
}
__except( STATUS_NO_MEMORY == GetExceptionCode() )
{
assert( !"Out Of Memory" );
}
}
#elif (_WIN32_WINNT >= 0x0403)
CCriticalSectionBase( ULONG nSpinCount = 4000 )
{
// SpinCount의 MS-SQL 기본값 : 4000
// 윈도우 2000에서는 아무리 많은 스핀 카운트를 쓰려고 하더라도
// 최상위 비트를 1로 세팅하지 말아야 한다.(MSDN 참조 - XP 이상은 최상위 비트가 무시된다.)
// nSpinCount = 0x80000400;
__try
{
BOOL bRet = InitializeCriticalSectionAndSpinCount( &m_CS, nSpinCount );
if( !bRet )
{
assert( !"Out Of Memory" );
}
}
__except( STATUS_NO_MEMORY == GetExceptionCode() )
{
assert( !"Out Of Memory" );
}
}
#endif
~CCriticalSectionBase()
{
DeleteCriticalSection( &m_CS ); // Critical Section 개체 삭제
}
inline void Enter()
{
__try
{
EnterCriticalSection( &m_CS ); // Critical Section 진입(Lock)
}
__except(STATUS_NO_MEMORY == GetExceptionCode())
{
assert( !"Out Of Memory" );
}
}
inline void Leave()
{
LeaveCriticalSection( &m_CS ); // Critical Section 해제(UnLock)
}
#if (_WIN32_WINNT >= 0x0403)
inline ULONG SetSpinCount( ULONG nSpinCount )
{
return( SetCriticalSectionSpinCount( &m_CS, nSpinCount ) );
}
#endif
#if(_WIN32_WINNT >= 0x0400)
inline BOOL TryEnter()
{
return( TryEnterCriticalSection( &m_CS ) );
}
#endif
private:
CRITICAL_SECTION m_CS; // Critical Section 개체
};
template <typename T>
class CMultiThreadSync
{
friend class CThreadSync;
public:
class CThreadSync
{
public:
CThreadSync()
{
T::m_SyncObject.Enter();
}
~CThreadSync()
{
T::m_SyncObject.Leave();
}
};
private:
static CCriticalSectionBase m_SyncObject;
};
template <typename T>
CCriticalSectionBase CMultiThreadSync<T>::m_SyncObject;
//
// FILE: CriticalSectionBase.h
//
// AUTHOR: - TTF(zone0000@dreamwiz.com)
//
// PROJECT: CriticalSection
//
// COMPONENT: CCriticalSectionBase
//
// DATE: 16.05.2007
//
// COMMENTS: - v1.0 (2007.05.16)
// Spin Count를 적용하여 윈도우 버전에 맞게 자동 선택
// try/catch문을 이용하여 동기화 객체 할당시 메모리 오류 assert 처리
//
//*******************************************************************
#pragma once
#include <assert.h>
// 스핀 카운트란? 싱글 Processor 시스템에서는 무시되는 항목이지만,
// 멀티 Processor 시스템에서 Critical Section을 사용할 수 없을 때
// 세마포어와 연계되어 작동하는데, 세마포어는 커널 모드에서 작동하므로
// 호출되는 스레드가 유저모드에서 대기(busy-waiting) 상태로 남아 있을 경우에
// 더욱 효율적일 수 있다.
// 요약 - 유저모드로 대기하는 스레드의 갯수에 대한 설정이다.
class CCriticalSectionBase
{
public:
#if (_WIN32_WINNT < 0x0403)
CCriticalSectionBase()
{
__try
{
InitializeCriticalSection( &m_CS );
}
__except( STATUS_NO_MEMORY == GetExceptionCode() )
{
assert( !"Out Of Memory" );
}
}
#elif (_WIN32_WINNT >= 0x0403)
CCriticalSectionBase( ULONG nSpinCount = 4000 )
{
// SpinCount의 MS-SQL 기본값 : 4000
// 윈도우 2000에서는 아무리 많은 스핀 카운트를 쓰려고 하더라도
// 최상위 비트를 1로 세팅하지 말아야 한다.(MSDN 참조 - XP 이상은 최상위 비트가 무시된다.)
// nSpinCount = 0x80000400;
__try
{
BOOL bRet = InitializeCriticalSectionAndSpinCount( &m_CS, nSpinCount );
if( !bRet )
{
assert( !"Out Of Memory" );
}
}
__except( STATUS_NO_MEMORY == GetExceptionCode() )
{
assert( !"Out Of Memory" );
}
}
#endif
~CCriticalSectionBase()
{
DeleteCriticalSection( &m_CS ); // Critical Section 개체 삭제
}
inline void Enter()
{
__try
{
EnterCriticalSection( &m_CS ); // Critical Section 진입(Lock)
}
__except(STATUS_NO_MEMORY == GetExceptionCode())
{
assert( !"Out Of Memory" );
}
}
inline void Leave()
{
LeaveCriticalSection( &m_CS ); // Critical Section 해제(UnLock)
}
#if (_WIN32_WINNT >= 0x0403)
inline ULONG SetSpinCount( ULONG nSpinCount )
{
return( SetCriticalSectionSpinCount( &m_CS, nSpinCount ) );
}
#endif
#if(_WIN32_WINNT >= 0x0400)
inline BOOL TryEnter()
{
return( TryEnterCriticalSection( &m_CS ) );
}
#endif
private:
CRITICAL_SECTION m_CS; // Critical Section 개체
};
template <typename T>
class CMultiThreadSync
{
friend class CThreadSync;
public:
class CThreadSync
{
public:
CThreadSync()
{
T::m_SyncObject.Enter();
}
~CThreadSync()
{
T::m_SyncObject.Leave();
}
};
private:
static CCriticalSectionBase m_SyncObject;
};
template <typename T>
CCriticalSectionBase CMultiThreadSync<T>::m_SyncObject;
[출처] [C++] 템플릿 기반 Critical Section 동기화 객체 |작성자 나디아
반응형
'운영체제 & 병렬처리 > Multithread' 카테고리의 다른 글
멀티쓰래드일때 멤버함수또한 동기화를 해줘야한다 (0) | 2012.12.26 |
---|---|
multi thread 를 이용한 로딩 화면 만들기 (0) | 2012.12.26 |
InitializeCriticalSectionAndSpinCount (0) | 2012.12.24 |
CreateThread, _beginthread, _beginthreadex 에 대한 정리 (0) | 2012.12.23 |
쓰래드와 Sleep (0) | 2012.12.22 |