//******************************************************************* // // 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// 스핀 카운트란? 싱글 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 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 CCriticalSectionBase CMultiThreadSync ::m_SyncObject;
[C++] 템플릿 기반 Critical Section 동기화 객체
프로그래밍/클래스 모음
2007/05/16 03:40
덧글을 달아 주세요