#ifndef __ZCPPMAIN__PROCESS_WIN_H__ #define __ZCPPMAIN__PROCESS_WIN_H__ #include "ZCppMain/ZMainHead.H" #include #include #include namespace ZNsMain { namespace ZNsEnum { /* In WinNT : #define STATUS_WAIT_0 ((DWORD )0x00000000L) In WinBase : #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) Լ 쿡 å , ZEThread_Invalid ̿ ȯ ִ. */ enum ZEThread { ZEThread_OK = 0, // =WAIT_OBJECT_0 ZEThread_Invalid =-1, // Լ . ZEThread_TimeOut = WAIT_TIMEOUT };/* enum ZEThread*/ /*################################################## barrier ǥ ȯ. barrier üũ BarrierClass VO_BarrierClass; if(VO_BarrierClass.Init()==ZEBarrier_NO) { // some code } . if(VO_BarrierClass.Init()!=ZEBarrier_OK) { // some code } ؾ ϴ. ##################################################*/ enum ZEBarrier { ZEBarrier_NO = false , ZEBarrier_OK = true };/* enum ZEBarrier*/ }/* namespace ZNsEnum*/ class ZCProcess { protected: STARTUPINFO mo_SI; PROCESS_INFORMATION mo_PI; public : bool Exec(LPCTSTR AP_ExeName, LPCTSTR APC_WorkDir=NULL, bool AB_Inherit=TRUE) { ::GetStartupInfoA(&mo_SI); return ::CreateProcessA( NULL , (LPSTR)AP_ExeName, // Name of app to launch NULL , // Default process security attributes NULL , // Default thread security attributes AB_Inherit , // Inherit handles from the parent 0 , // Normal priority NULL , // Use the same environment as the parent APC_WorkDir , // Launch in the current directory &mo_SI , // Startup Information &mo_PI // Process information stored upon return /*/////////*/ ) == TRUE ; }/* bool Exec(LPCTSTR AP_ExeName, LPCTSTR APC_WorkDir=NULL, bool AB_Inherit=TRUE)*/ HANDLE GetNowProcessHandle() { return ::GetCurrentProcess(); }/* HANDLE GetNowProcessHandle()*/ static long GetPID() { return ::GetCurrentProcessId(); // DWORD GetCurrentProcessId(VOID); }/* static long GetPID()*/ STARTUPINFO& GetStartUpInfo() { return mo_SI; }/* STARTUPINFO& GetStartUpInfo()*/ PROCESS_INFORMATION& GetProcInfo() { return mo_PI; }/* PROCESS_INFORMATION& GetProcInfo()*/ public: };/* class ZCProcess*/ ////////////////////////////////////////// /////////// end class ZCProcess /////////// ////////////////////////////////////////// // Memory Map class class ZCMemMap { private: HANDLE mh_MemMap; public : ZCMemMap() { mh_MemMap=NULL; }/* ZCMemMap()*/ /*//////////////////////////////////////////////////////////////////////////// ZTypLong ALL_Size 0 ̸ AH_File ũⰡ ״ ȴ. AH_File ִ ALL_Size 1 ̻ ؾ . AH_File ȿ ̰ ALL_Size 1 ̻ ̸ AH_File ũⰡ ALL_Size ȴ. ////////////////////////////////////////////////////////////////////////////*/ bool Create(HANDLE AH_File=INVALID_HANDLE_VALUE, ZTypLong ALL_Size=0, DWORD ADW_ProtectFlag=PAGE_READWRITE, ::LPSECURITY_ATTRIBUTES AP_FileMappingAttributes=NULL, LPCTSTR AP_Name=NULL) { ::LARGE_INTEGER LI; LI.QuadPart=ALL_Size; return (mh_MemMap=::CreateFileMapping( AH_File, AP_FileMappingAttributes, ADW_ProtectFlag, LI.HighPart, LI.LowPart, AP_Name))!=NULL; }/* bool Create(HANDLE AH_File=INVALID_HANDLE_VALUE, ZTypLong ALL_Size=0, DWORD ADW_ProtectFlag=PAGE_READWRITE, ::LPSECURITY_ATTRIBUTES AP_FileMappingAttributes=NULL, LPCTSTR AP_Name=NULL)*/ /* LPVOID AP_BaseAddress Ѵٸ system's memory allocation granularity Ѵ. granularity ˱ ؼ GetSystemInfo Ѵ. VOID GetSystemInfo(LPSYSTEM_INFO lpSystemInfo) . NULL ̸ ý ˾Ƽ Ѵ. */ /* DWORD ADW_MapSize 0 ̸ ü map ȴ. */ LPVOID LinkMap(ZTypLong ALL_Offset=0, DWORD ADW_MapSize=0, DWORD ADW_DesiredAccess=FILE_MAP_ALL_ACCESS, LPVOID AP_BaseAddress=NULL) const { ::LARGE_INTEGER LI; LI.QuadPart=ALL_Offset; return ::MapViewOfFileEx( mh_MemMap, ADW_DesiredAccess, LI.HighPart, LI.LowPart, ADW_MapSize, AP_BaseAddress); }/* LPVOID LinkMap(ZTypLong ALL_Offset=0, DWORD ADW_MapSize=0, DWORD ADW_DesiredAccess=FILE_MAP_ALL_ACCESS, LPVOID AP_BaseAddress=NULL) const*/ bool UnMap(LPCVOID AP_BaseAddress) const { return ::UnmapViewOfFile((void*)AP_BaseAddress)==TRUE; }/* bool UnMap(LPCVOID AP_BaseAddress) const*/ /* cygwin ̳ mingw ̻ϰ ::UnmapViewOfFile(void*) ǵǾ ִ. ׷ UnMap() μ (void*)AP_BaseAddress ȯְ ִ. */ bool Close() { const bool CB_IsOK = (::CloseHandle(mh_MemMap)==TRUE); mh_MemMap=NULL; return CB_IsOK; }/* bool Close()*/ public: };/* class ZCMemMap*/ // ޸ Ŭ class ZCShareMemory { private: ZTypeID mh_FileMap; void* mp_Address; public : ZCShareMemory() { mh_FileMap=0; mp_Address=0; }/* ZCShareMemory()*/ ZTypeID GetID() const { return mh_FileMap; }/* ZTypeID GetID() const*/ bool IsValidID() const { return mh_FileMap!=0; }/* bool IsValidID() const*/ void* GetStartAddress() const { return mp_Address; }/* void* GetStartAddress() const*/ // Create() ȣ LinkMap() ȣؾ Ѵ. bool Create(LPCTSTR AP_MapName, long AL_MapSize) { return (mh_FileMap = ::CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, AL_MapSize, AP_MapName))!=NULL ; /*////////////////////////////////////////////////////// HANDLE CreateFileMapping ( HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCTSTR lpName ); lpName The name of the file mapping object. If this parameter matches the name of an existing mapping object, the function requests access to the object with the protection that flProtect specifies. If this parameter is NULL, the file mapping object is created without a name. If lpName matches the name of an existing event, semaphore, mutex, waitable timer, or job object, the function fails, and the GetLastError function returns ERROR_INVALID_HANDLE. This occurs because these objects share the same namespace. -- lpName ̸ event, semaphore, mutex, waitable timer  -- ϰ ִٸ GetLastError Լ ERROR_INVALID_HANDLE ȯѴ. -- NULL ִ. Return Value If the function succeeds, the return value is a handle to the file mapping object. If the object exists before the function call, the function returns a handle to the existing object (with its current size, not the specified size), and GetLastError returns ERROR_ALREADY_EXISTS. If the function fails, the return value is NULL. To get extended error information, call GetLastError. //////////////////////////////////////////////////////*/ }/* bool Create(LPCTSTR AP_MapName, long AL_MapSize)*/ bool Create(long AL_MapSize) { return this->Create(NULL/*lpMapName*/, AL_MapSize); }/* bool Create(long AL_MapSize)*/ /*/////////////////////////////////////////////////////////////////////////////// LPVOID MapViewOfFile ( HANDLE hFileMappingObject , DWORD dwDesiredAccess , DWORD dwFileOffsetHigh , DWORD dwFileOffsetLow , DWORD dwNumberOfBytesToMap ); hFileMappingObject FILE_MAP_ALL_ACCESS Equivalent to FILE_MAP_WRITE and FILE_MAP_READ. The object must have been created with the PAGE_READWRITE option. FILE_MAP_COPY A copy-on-write view of the file is mapped. The object must have been created with the PAGE_WRITECOPY option. If the file mapping object is backed by the operating system paging file, the system commits physical storage from the paging file at the time that MapViewOfFile is called. The actual physical storage is not used until a thread in the process writes to an address in the view. At that time, the system copies the original page to a new page that is backed by the paging file, maps the page into the process address space, and changes the page protection to PAGE_READWRITE. The threads in the process can access only the local copy of the data, not the original data. If the page is ever trimmed from the working set of the process, it can be written to the paging file storage that is committed when MapViewOfFile is called. This process only allocates physical memory when a virtual address is actually written to. Changes are never written back to the original file, and are freed when the thread in your process unmaps the view. Paging file space for the entire view is committed when copy-on-write access is specified, because the thread in the process can write to every single page. Therefore, enough physical storage space must be obtained at the time MapViewOfFile is called. FILE_MAP_EXECUTE An executable view of the file is mapped (mapped memory can be run as code). The object must have been created with the PAGE_EXECUTE_READWRITE or PAGE_EXECUTE_READ option. Windows Server 2003 and Windows XP: This value is available starting with Windows XP SP2 and Windows Server 2003 SP1. Windows 2000: This value is not supported. -- FILE_MAP_EXECUTE Ȯ ϴ 𸣰ڴ. -- ڵμ ִٴ , ڵ  ϴ ΰ. -- 2008-02-08 21:48:00 FILE_MAP_READ A read-only view of the file is mapped. The object must have been created with the PAGE_READWRITE or PAGE_READONLY option. FILE_MAP_WRITE A read/write view of the file is mapped. The object must have been created with the PAGE_READWRITE option. dwFileOffsetHigh A high-order DWORD of the file offset where the view begins. dwFileOffsetLow A low-order DWORD of the file offset where the view is to begin. The combination of the high and low offsets must specify an offset within the file mapping. They must also match the memory allocation granularity of the system. That is, the offset must be a multiple of the allocation granularity. To obtain the memory allocation granularity of the system, use the GetSystemInfo function, which fills in the members of a SYSTEM_INFO structure. dwNumberOfBytesToMap The number of bytes of a file mapping to map to the view. All bytes must be within the maximum size specified by CreateFileMapping. If this parameter is 0 (zero), the mapping extends from the specified offset to the end of the file mapping. ///////////////////////////////////////////////////////////////////////////////*/ bool LinkMap(DWORD dwDesiredAccess=FILE_MAP_ALL_ACCESS, DWORD dwNumberOfBytesToMap=0) { return (mp_Address=::MapViewOfFile(mh_FileMap, dwDesiredAccess, 0, 0, dwNumberOfBytesToMap))!=0 ; }/* bool LinkMap(DWORD dwDesiredAccess=FILE_MAP_ALL_ACCESS, DWORD dwNumberOfBytesToMap=0)*/ bool UnMap() { bool VB_IsOK = (::UnmapViewOfFile(mp_Address)==TRUE) ; mp_Address=0; return VB_IsOK; }/* bool UnMap()*/ bool Close() { bool VB_IsOK = (::CloseHandle(mh_FileMap)==TRUE); mh_FileMap=0; return VB_IsOK; }/* bool Close()*/ public: };/* class ZCShareMemory*/ /////////////////////////////////////////////// /////////// end class ZCShareMemory /////////// /////////////////////////////////////////////// /*////////////////////////////////////////////////////////////////////////////// class ZCProcessMutex μ ؽ. Window ̸ִ mutex Linux  ͵ ̴. pthread ̺귯 Ἥ ޸𸮿 mutex Ÿ  ټ ϴ. Linux ߾忡 μ  ٸ. Ȯ pthread μ mutex ʴ´. (2006-12-28 16:02:00) window ؽ '' ־ ؽ ؾ Ѵ. ؽ ReleaseMutex(ؽ) ϸ FALSE ȯѴ. ش ؽ ؽ ƹ ɾ ī Ʈ ö ʴ´. īƮŭ ־ Ѵ. //////////////////////////////////////////////////////////////////////////////*/ class ZCProcessMutex { private: ZTypeID mh_Mutex; public : ZCProcessMutex() { mh_Mutex=0; }/* ZCProcessMutex()*/ ZTypeID GetHandle() const { return mh_Mutex; }/* ZTypeID GetHandle() const*/ bool Make(LPCTSTR AP_MutexName=NULL, LPSECURITY_ATTRIBUTES lpMutexAttributes=NULL, BOOL bInitialOwner=FALSE) { if(lpMutexAttributes==NULL) { // Mutex ڵ ϵ μ ְ Ѵ. SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES_Obj; SECURITY_ATTRIBUTES_Obj.bInheritHandle =TRUE; SECURITY_ATTRIBUTES_Obj.lpSecurityDescriptor=NULL; SECURITY_ATTRIBUTES_Obj.nLength =sizeof(SECURITY_ATTRIBUTES); return (mh_Mutex = ::CreateMutex(&SECURITY_ATTRIBUTES_Obj, bInitialOwner, AP_MutexName))!=NULL ; }/* if(lpMutexAttributes==NULL)*/ return (mh_Mutex = ::CreateMutex(lpMutexAttributes, bInitialOwner, AP_MutexName))!=NULL ; }/* bool Make(LPCTSTR AP_MutexName=NULL, LPSECURITY_ATTRIBUTES lpMutexAttributes=NULL, BOOL bInitialOwner=FALSE)*/ bool Lock(DWORD ADW_TimeOut=INFINITE) { DWORD VI_Return=::WaitForSingleObject(mh_Mutex, ADW_TimeOut); return VI_Return!=WAIT_ABANDONED && VI_Return!=WAIT_FAILED ; /*/////////////////////////////////////////////////////////////////////////// WaitForSingleObject() Լ ش ؽ ȣ° ƴϸ ȣ· ְ ٷ , ȣ̸ ȣ° Ѵ. 尡 ý ϸ ؽ ٸ ٸ ° ȴ. ׷ ؽ 尡  ؽ Ǯ ϰ Ǹ ؽ(Abandoned Mutex) Ҹ. WaitForSingleObject() Լ ϰ WAIT_ABANDONED ޹޴ ̸ ؽ  ó ΰ α׷ӿ ޸ ̴. ̰ Critical Section ణ ġ ִ. ///////////////////////////////////////////////////////////////////////////*/ }/* bool Lock(DWORD ADW_TimeOut=INFINITE)*/ int LockRaw(DWORD ADW_TimeOut=INFINITE) { return ::WaitForSingleObject(mh_Mutex, ADW_TimeOut); }/* int LockRaw(DWORD ADW_TimeOut=INFINITE)*/ int LockTime(DWORD AI_TimeOutMili) { return LockRaw(AI_TimeOutMili); }/* int LockTime(DWORD AI_TimeOutMili)*/ bool UnLock() { return ::ReleaseMutex(mh_Mutex)==TRUE ; }/* bool UnLock()*/ bool Close() { bool VB_Result=(::CloseHandle(mh_Mutex)==TRUE) ; mh_Mutex=0; return VB_Result; }/* bool Close()*/ public: };/* class ZCProcessMutex*/ /////////////////////////////////////////////// /////////// end class ZCProcessMutex /////////// /////////////////////////////////////////////// class ZCProcessMutexEasy : protected ZCProcessMutex { public: ZCProcessMutexEasy(LPCTSTR AP_MutexName) { if(this->ZCProcessMutex::Make(AP_MutexName)==false) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<ZCProcessMutex::Make(AP_MutexName)==false)*/ }/* ZCProcessMutexEasy(LPCTSTR AP_MutexName)*/ ZCProcessMutexEasy() { if(this->ZCProcessMutex::Make()==false) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<ZCProcessMutex::Make()==false)*/ }/* ZCProcessMutexEasy()*/ /*////////////////////////////////////////////////////////// Ʒ ٿ ZCProcessMutex() Ϳ ؼ CProcess_Linux.H class ZZCThreadMutexEasy ּ . -- 2013-05-05 07:05:00 //////////////////////////////////////////////////////////*/ ZCProcessMutexEasy(const ZCProcessMutexEasy& rhs) : ZCProcessMutex() { if(this->ZCProcessMutex::Make()==false) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<ZCProcessMutex::Make()==false)*/ }/* ZCProcessMutexEasy(const ZCProcessMutexEasy& rhs)*/ ~ZCProcessMutexEasy() { if(this->ZCProcessMutex::Close()==false) { std::fstream fileout("DEBUG.txt",std::ios::out | std::ios::app); fileout<ZCProcessMutex::Close()==false)*/ }/* ~ZCProcessMutexEasy()*/ using ZCProcessMutex::Lock ; using ZCProcessMutex::UnLock; public: };/* class ZCProcessMutexEasy*/ typedef ZCProcessMutexEasy ZZCThreadMutexEasy; /*///////////////////////////////////////////////////////////// class ZCProcessSemaphore μ ȭ object. μ ȭ Semaphore ְ Window μ ȭ Mutex ִ. μ ȭ ̴ Semaphore ȭ ̴  Լ ٸ. class ZCThreadSemaphore ȣȯDZ ƴ. ȣȯ ؼ class ZCProcessSemaphore . 쿡 ̸ִ semaphore μ ̴. ReleaseSemaphore() Լ ϴ ڿ 2 ̻ ϴ ǰ ִ 尡 2 ̻  ƴϴ. ݵ 忡 ڽ ŭ ־ Ѵ. Posix barrier Ȯ . /////////////////////////////////////////////////////////////*/ class ZCProcessSemaphore { private: ZTypeID mh_Semaphore; public : ZCProcessSemaphore() { mh_Semaphore=0; }/* ZCProcessSemaphore()*/ ~ZCProcessSemaphore() { Close(); }/* ZCProcessSemaphore*/ bool Make(LPCSTR AP_SemaName, LONG AL_InitialCnt, LONG AL_MaximumCount, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes=NULL) { /*///////////////////////////////////////////////////////////////// cf) CreateSemaphore() Return Values If the function succeeds, the return value is a handle to the semaphore object. If the named semaphore object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. If the function fails, the return value is NULL. To get extended error information, call GetLastError. /////////////////////////////////////////////////////////////////*/ return (mh_Semaphore = ::CreateSemaphoreA( AP_SemaphoreAttributes, AL_InitialCnt, AL_MaximumCount, AP_SemaName))!=(HANDLE)ERROR_INVALID_HANDLE ; }/* bool Make(LPCSTR AP_SemaName,LONG AL_InitialCnt, LONG AL_MaximumCount, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes=NULL)*/ bool Make(LPCSTR AP_SemaName, LONG AL_InitialCnt, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes=NULL) { return (mh_Semaphore = ::CreateSemaphoreA( AP_SemaphoreAttributes, AL_InitialCnt, AL_InitialCnt, AP_SemaName))!=(HANDLE)ERROR_INVALID_HANDLE ; }/* bool Make(LPCSTR AP_SemaName, LONG AL_InitialCnt, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes=NULL)*/ // Ʒ ؽó 쿡 Ѵ. bool Make(LONG AL_InitialCnt=1, LONG AL_MaxCnt=1, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes=NULL) { return (mh_Semaphore=::CreateSemaphore( AP_SemaphoreAttributes, AL_InitialCnt, AL_MaxCnt, this->GetUniqueSemaKey()) )!=(HANDLE)ERROR_INVALID_HANDLE ; }/* bool Make(LONG AL_InitialCnt=1, LONG AL_MaxCnt=1, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes=NULL)*/ bool MakeZero(LPCSTR AP_SemaName=NULL) // ȣ  . { const int CI_MaxNumSemaphore=2100000000; return (mh_Semaphore=::CreateSemaphoreA( NULL, 0, CI_MaxNumSemaphore, AP_SemaName))!=(HANDLE)ERROR_INVALID_HANDLE ; }/* bool MakeZero(LPCSTR AP_SemaName=NULL)*/ static LPCSTR GetUniqueSemaKey() { static long SL_UniqueID=0 ; const long CL_AddID =100000; long VL_UniqueLong = ( SL_UniqueID += CL_AddID ) + ::GetCurrentProcessId() ; static char VCA_Buff[100]; ::wsprintf(VCA_Buff, _T("SemaKey%ld"), VL_UniqueLong); return VCA_Buff; }/* static LPCSTR GetUniqueSemaKey()*/ /* bool MakeStd() class ZCProcessSemaphore Window, Linux ʿ ȣȯϱ */ bool MakeStd(LPCSTR AP_SemaName, LONG AL_InitialCnt,LONG AL_MaximumCount) { return this->Make(AP_SemaName, AL_InitialCnt, AL_MaximumCount); }/* bool MakeStd(LPCSTR AP_SemaName, LONG AL_InitialCnt, LONG AL_MaximumCount)*/ bool Open(LPCSTR AP_SemaName, DWORD dwDesireAccess=SEMAPHORE_ALL_ACCESS, BOOL bInheritHandle=TRUE) { return (mh_Semaphore=::OpenSemaphore(dwDesireAccess, bInheritHandle, AP_SemaName))!=NULL ; }/* bool Open(LPCSTR AP_SemaName, DWORD dwDesireAccess=SEMAPHORE_ALL_ACCESS, BOOL bInheritHandle=TRUE)*/ /* ´. Լ ۰ ڽ ڽ ٰ ϰ ִ. 'API ' 1101 . Լ ʿϳĐ  ʿϴ. -- 2015-09-16 00:40:00 */ static int GetValue(HANDLE AH_Sema) { if(::WaitForSingleObject(AH_Sema, 0)==WAIT_TIMEOUT) return 0; LONG VL_Count=0; ::ReleaseSemaphore(AH_Sema, 1, &VL_Count); return VL_Count+1; /*#####################################*/ }/* static int GetValue(HANDLE AH_Sema)*/ int GetValue() const { return GetValue(mh_Semaphore); }/* int GetValue() const*/ bool IsZeroCount() { return ::WaitForSingleObject(mh_Semaphore, 0)==WAIT_TIMEOUT; }/* bool IsZeroCount()*/ // cf) WaitForSingleObject() ðʰ 쿡 WAIT_TIMEOUT Ѵ. bool Lock(DWORD ADW_TimeOut=INFINITE) { return ::WaitForSingleObject(mh_Semaphore, ADW_TimeOut)!=WAIT_FAILED; }/* bool Lock(DWORD ADW_TimeOut=INFINITE)*/ /* LockRaw() ̸ ZEThread_OK, ðʰ ZEThread_TimeOut ȯѴ. Posix  . */ int LockRaw(DWORD ADW_TimeOut=INFINITE) { return ::WaitForSingleObject(mh_Semaphore, ADW_TimeOut); }/* int LockRaw(DWORD ADW_TimeOut=INFINITE)*/ int LockTime(DWORD AI_TimeOutMili) { return LockRaw(AI_TimeOutMili); }/* int LockTime(DWORD AI_TimeOutMili)*/ bool UnLock(LONG lReleaseCount=1, LPLONG lpPreviousCount=NULL) { /* cf) lReleaseCount [in] Amount by which the semaphore object's current count is to be increased. The value must be greater than zero. If the specified amount would cause the semaphore's count to exceed the maximum count that was specified when the semaphore was created, the count is not changed and the function returns FALSE. */ return ::ReleaseSemaphore(mh_Semaphore, lReleaseCount, lpPreviousCount)!=0 ; }/* bool UnLock(LONG lReleaseCount=1, LPLONG lpPreviousCount=NULL)*/ bool Close() { if(mh_Semaphore==0) return true; const bool CB_IsOK =( ::CloseHandle(mh_Semaphore)==TRUE) ; mh_Semaphore=0; return CB_IsOK; }/* bool Close()*/ public: };/* class ZCProcessSemaphore*/ //////////////////////////////////////////////// /////////// end class ZCProcessMutex /////////// //////////////////////////////////////////////// /*////////////////////////////////////////////// 쿡 μ  ʿ䰡 . 忡 ::EnterCriticalSection() ߺ ȣ ʴ´. Mutex . //////////////////////////////////////////////*/ typedef ZCProcessSemaphore ZCThreadSemaphore; typedef ZCProcessMutex ZCThreadMutex ; typedef ZCProcessMutex ZCThreadMutexStd ; // posix spin lock Ѵ. class ZCCriticSect // Critical Section { private: CRITICAL_SECTION mo_CriticSect; public : void Init() { ::InitializeCriticalSection(&mo_CriticSect); }/* void Init()*/ bool Init(DWORD AI_SpinCount) { return ::InitializeCriticalSectionAndSpinCount(&mo_CriticSect, AI_SpinCount)==TRUE; }/* bool Init(DWORD AI_SpinCount)*/ void Fini() { ::DeleteCriticalSection(&mo_CriticSect); }/* void Fini()*/ void Lock (){::EnterCriticalSection(&mo_CriticSect);} void UnLock(){::LeaveCriticalSection(&mo_CriticSect);} /*////////////////////////////////////////////////////////////////////////////////// ̻ϰ TryEnterCriticalSection Լ ȣ . -- 2007-05-17 14:34:00) bool TryLock() { return TryEnterCriticalSection(&mo_CriticSect)==TRUE; } /////////////////////////////////////////////////////////////////////////////////////*/ #if defined(__VISUAL_CPP_VER__) && __VISUAL_CPP_VER__>=200800 bool WaitCond(::PCONDITION_VARIABLE AP_Cond, DWORD AI_Mili=INFINITE) { return ::SleepConditionVariableCS(AP_Cond, &mo_CriticSect, AI_Mili)==TRUE; }/* bool WaitCond(::PCONDITION_VARIABLE AP_Cond, DWORD AI_Mili=INFINITE)*/ #endif //defined(__VISUAL_CPP_VER__) && __VISUAL_CPP_VER__>=200800 public: };/* class ZCCriticSect*/ class ZCCriticSectEasy : protected ZCCriticSect { public: ZCCriticSectEasy(){this->Init();} ZCCriticSectEasy(const ZCCriticSectEasy&){this->Init();} ~ZCCriticSectEasy(){this->Fini();} void Lock (){this->ZCCriticSect::Lock ();} void UnLock(){this->ZCCriticSect::UnLock();} public: };/* class ZCCriticSectEasy : public ZCCriticSect*/ typedef ZCCriticSectEasy ZCDefLockEasy ; typedef ZCCriticSectEasy ZCFastLockEasy; template class ZtCAutoKeyRev; /* ZtCAutoKey<> ø Lock ϰ Ѵ. ִ Key Ͽ. ̷ RAII(Resource Acquisition Is Initialization) Ѵٴ ˾Ҵ. -- 2015-03-10 15:08:00 */ template class ZtCAutoKey { public : template friend class ZtCAutoKeyRev; private: ZtCAutoKey(const ZtCAutoKey& rhs){} private: TCriticSectEasy& mr_SyncEasy; #ifdef _DEBUG_CAUTOKEY_ static int msi_CallCnt; #endif //_DEBUG_CAUTOKEY_ public: ZtCAutoKey(TCriticSectEasy& AR_SyncEasy):mr_SyncEasy(AR_SyncEasy) { #ifdef _DEBUG_CAUTOKEY_ cout<<" ZtCAutoKey:: ZtCAutoKey() "< class ZtCAutoKey */ #ifdef _DEBUG_CAUTOKEY_ template int ZtCAutoKey::msi_CallCnt = 0; #endif //_DEBUG_CAUTOKEY_ /*//////////////////////////////////////////////////////////////// ZtCAutoKeyRev<> ZtCAutoKey<> ڿ μ ޾Ƽ ڿ Lock ϰ, Ҹڿ ٽ Lock ɾ ش. ׷ ̷ ؾ Ȳ ü . ϴ Dead Lock ¿ . 2008-04-09 21:01:00 ////////////////////////////////////////////////////////////////*/ template class ZtCAutoKeyRev { private: TAutoKey& mr_CAutoKey; public : ZtCAutoKeyRev(TAutoKey& AR_CAutoKey):mr_CAutoKey(AR_CAutoKey) { mr_CAutoKey.mr_SyncEasy.UnLock(); }/* ZtCAutoKeyRev(TAutoKey& AR_CAutoKey)*/ ~ZtCAutoKeyRev() { mr_CAutoKey.mr_SyncEasy.Lock(); }/* ~ZtCAutoKeyRev()*/ public: };/* template class ZtCAutoKeyRev */ /*//////////////////////////////////////////////////// http://blog.naver.com/kimsk99?Redirect=Log&logNo=50004383787 α׷ ϸ鼭 带 , CreateThread _beginthread Լ ,  Լ ؾ ϰ ȴ. ׻ ⺻ API CreateThread Ծ. ׷ å дٰ װ ߸Ǿٴ ˾Ҵ. MSDN ڼ о ̾ ڼ ׵ . ϴ CreateThread SDK ϴ ⺻ API ̴. Ư ̺귯 ũ ʾƵ ϵǰ ư. _beginthread(Ǵ _beginthreadex) standard C library Լ ũؾ Ѵ. ׷ ɿ ̰ . ɿ ̰ ʴ´ٸ ̷ ̴. _beginthread ޶ ʿ 찡 ִ. ׷ Լ _beginthreadex CreateThread ڸ ִ. ׷ CreateThread _beginthreadex ġȯ ϴ. εۿ ū _beginthread standard C library ϴ TLB ʱȭ شٴ ̴. standary C library ִ Լ Ϻδ thread-safty ؼ TLB ϴµ ʱȭ ʴ´ٸ ߻ ִ. _beginthreadex Լ ؼ 带 ߴٸ Լ 带 ϱ ؼ ExitThread Լ ϱ ٴ _endthreadex Լ ϱ Ѵ. κ C library ϱ _beginthreadex ؾ Ѵ. uintptr_t _beginthreadex ( void *security, unsigned stack_size, unsigned ( *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); -- ////////////////////////////////////////////////////*/ ////////////////////////////////////////////////////// ///////////////// Ŭ ///////////////// ////////////////////////////////////////////////////// /*//////////////////////////////////////////////////// uintptr_t _beginthreadex ( void *security, unsigned stack_size, unsigned ( __stdcall *start_address )( void * ), void *arglist, unsigned initflag, unsigned *thrdaddr ); HANDLE CreateThread ( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE AP_StartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); CreateThread _beginthreadex ü ְ ׷ Ѵ. dwCreationFlags [in] Flags that control the creation of the thread. If the CREATE_SUSPENDED flag is specified, the thread is created in a suspended state, and will not run until the ResumeThread function is called. If this value is zero, the thread runs immediately after creation. If the STACK_SIZE_PARAM_IS_A_RESERVATION flag is specified, the dwStackSize parameter specifies the initial reserve size of the stack. Otherwise, dwStackSize specifies the commit size. Windows 2000/NT and Windows Me/98/95: The STACK_SIZE_PARAM_IS_A_RESERVATION flag is not supported. lpThreadId [out] Pointer to a variable that receives the thread identifier. If this parameter is NULL, the thread identifier is not returned. Windows Me/98/95: This parameter may not be NULL. cf) DWORD ResumeThread( HANDLE hThread ); **** IN WINBASE.H **** typedef DWORD (WINAPI *PTHREAD_START_ROUTINE) ( LPVOID lpThreadParameter ); typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; LPTHREAD_START_ROUTINE AP_StartAddress Լ DWORD WINAPI ThreadFunc(LPVOID lpRarameter) ********** MFC ȭ object ********** Ʒ object ؼ ʿ 1) CCriticalSection cs; cs.Lock(); // ۾ڵ cs.Unlock(); 2) CEvent event; Thread ֵ Ǵ CEvent object ϰ Thread CallBack Լ UINT ThreadFunc(LPVOID pParam) { while(TRUE) { CEventOvj.Lock(); // ̵. // ̺Ʈ ߻ ڵ带 ´. // ׸ ܺο // CEventOvj.PulseEvent(); ̳ // CEventOvj.SetEvent(); ȣϸ . // Thread Lock ɷ ¿ // PulseEvent Լ ȣϸ ƹϵ Ͼ ʰ // ٷ Lock() ȣϸ ٽ ܴ. // SetEvent() 쿡 ׳ Ѵ. } //while(TRUE) } //UINT ThreadFunc(LPVOID pParam) # Window Thread Callback Type; DWORD WINAPI ThreadFunc(LPVOID lpParameter); cf) typedef unsigned long DWORD; # Linux Thread Callback Type: void* ThreadFunc()(void*) ////////////////////////////////////////////////////*/ typedef DWORD ThreadReturnType ; typedef HANDLE ThreadID ; /*/////////////////////////////////////////////////////////////////// typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; LPVOID lpSecurityDescriptor; BOOL bInheritHandle; } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; ///////////////////////////////////////////////////////////////////*/ #define _THREAD_RETURN_ unsigned __stdcall namespace ZNsIFace { class ZCThread_BASE{}; }/* namespace ZNsIFace*/ template< typename TTypeBase=ZNsIFace::ZCThread_BASE > class ZtCThread : public TTypeBase /////////////////// { protected: ThreadID mh_ThreadID; public : ZtCThread() { _DEBUG_REENTRANT_CHECK_ mh_ThreadID = INVALID_HANDLE_VALUE ; }/* ZtCThread()*/ ZtCThread(TTypeBase& AR_CBaseType):TTypeBase(AR_CBaseType) { _DEBUG_REENTRANT_CHECK_ }/* ZtCThread(TTypeBase& AR_CBaseType):TTypeBase(AR_CBaseType)*/ ZtCThread(const ZtCThread& rhs):TTypeBase(rhs) { _DEBUG_REENTRANT_CHECK_ mh_ThreadID =rhs.mh_ThreadID ; (TTypeBase&)(*this)=static_cast(rhs); }/* ZtCThread(TTypeBase& AR_CBaseType):TTypeBase(AR_CBaseType)*/ template ZtCThread(const TTypeArg& AR_TTypeArg):TTypeBase(AR_TTypeArg) { _DEBUG_REENTRANT_CHECK_ }/* template ZtCThread(const TTypeArg& AR_TTypeArg):TTypeBase(AR_TTypeArg) */ ZtCThread& operator=(const ZtCThread& rhs) { return *this; // nothing to do }/* ZtCThread& operator=(const ZtCThread& rhs)*/ operator ThreadID () const { return mh_ThreadID; }/* operator ThreadID () const*/ ThreadID GetThreadID() const { return mh_ThreadID; }/* ThreadID GetThreadID() const*/ /*/////////////////////////////////////////////////// typedef DWORD (WINAPI *PTHREAD_START_ROUTINE) ( LPVOID lpThreadParameter ); typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; ///////////////////////////////////////////////////*/ bool Make(LPTHREAD_START_ROUTINE AP_StartAddress, void* AP_Arg=0, DWORD dwCreationFlags=0, DWORD dwStackSize=0, LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL) { unsigned int VUI_ThreadID; return ( mh_ThreadID = (void*)::/*CreateThread*/_beginthreadex ( lpThreadAttributes , dwStackSize , (unsigned int (__stdcall *)(void *))AP_StartAddress , AP_Arg , dwCreationFlags , &VUI_ThreadID ) /*****/ )!=INVALID_HANDLE_VALUE ; ////////////////////////////////// #if 0 // CreateThread() Լ DWORD VUI_ThreadID; return ( mh_ThreadID=::CreateThread ( lpThreadAttributes, dwStackSize, AP_StartAddress, AP_Arg, dwCreationFlags, &VUI_ThreadID ) /*****/ )!=INVALID_HANDLE_VALUE ; #endif }/* bool Make(LPTHREAD_START_ROUTINE AP_StartAddress, void* AP_Arg=0, DWORD dwCreationFlags=0, DWORD dwStackSize=0, LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL)*/ bool Make(unsigned (__stdcall *AP_StartAddress)(void *), void* AP_Arg=0, DWORD dwCreationFlags=0, DWORD dwStackSize=0, LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL) { unsigned int VUI_ThreadID; return ( mh_ThreadID=(void*)::_beginthreadex ( lpThreadAttributes , dwStackSize , AP_StartAddress , AP_Arg , dwCreationFlags , &VUI_ThreadID ) /*****/ )!=INVALID_HANDLE_VALUE ; ///////////// }/* bool Make(unsigned (__stdcall AP_StartAddress*)(void *), void* AP_Arg=0, DWORD dwCreationFlags=0, DWORD dwStackSize=0, LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL)*/ // ñ Լ ()Ų. int Wait(DWORD ADW_MilliSeconds=INFINITE) { return ::WaitForSingleObject(mh_ThreadID, ADW_MilliSeconds); /* WaitForSingleObject(HANDLE,DWORD ADW_MilliSeconds); 3 ȯ ´. WAIT_OBJECT_0 : HANDLE object ȣ° Ǿ. WAIT_TIMEOUT : ŸӾƿð Ͽ. WAIT_ABANDONED : ؽ */ }/* int Wait(DWORD ADW_MilliSeconds=INFINITE)*/ static int Wait(ThreadID AI_ThreadIDVar, DWORD ADW_MilliSeconds=INFINITE) { return ::WaitForSingleObject(AI_ThreadIDVar, ADW_MilliSeconds); /* WaitForSingleObject(HANDLE,DWORD ADW_MilliSeconds); 3 ȯ ´. WAIT_OBJECT_0 : HANDLE object ȣ° Ǿ. WAIT_TIMEOUT : ŸӾƿð Ͽ. WAIT_ABANDONED : ؽ */ }/* static int Wait(ThreadID AI_ThreadIDVar, DWORD ADW_MilliSeconds=INFINITE)*/ bool Terminate(DWORD AI_ExitCode=0) { return ::TerminateThread(mh_ThreadID, AI_ExitCode)==TRUE; }/* bool Terminate(DWORD AI_ExitCode=0)*/ /*//////////////////////////////////////////////////////// BOOL GetExitCodeThread( HANDLE hThread, LPDWORD lpExitCode ); Parameters hThread [in] Handle to the thread. lpExitCode [out] Pointer to a 32-bit variable to receive the thread termination status. Return Values Nonzero indicates success. Zero indicates failure. To get extended error information, call GetLastError. Remarks If the specified thread has not terminated, the termination status returned is STILL_ACTIVE. The following termination statuses can be returned if the process has terminated: The exit value specified in the ExitThread or TerminateThread function The return value from the thread function The exit value of the thread's process ////////////////////////////////////////////////////////*/ BOOL GetExitCode(DWORD& ARRDW_ExitCode) { return ::GetExitCodeThread(mh_ThreadID, &ARRDW_ExitCode); }/* BOOL GetExitCode(DWORD& ARRDW_ExitCode)*/ /*////////////////////////////////////////////////////////////// SuspendThread Լ Ű ResumeThread Լ 带 ۽Ų. ī͸ ϴµ īƮ SuspendThread Լ ȣǸ ϰ ResumeThread Լ ȣ Ǹ ϸ īƮ 0 ̸ 簳ȴ. ׷ SuspendThread Լ ι ȣߴٸ ResumeThread Լ ι ȣ ־ 尡 簳ȴ. ׷ٸ ResumeThread ȣϰ SuspendThread ߿ ȣϸ  ɱ. 쿡 ȴ. īƮ -1 0 Ǿ īƮ 0 ̸δ ʴ . POSIX ǥؾȿ ̷ Լ µ, POSIX 带 α׷ (ȭ, David R. Butenhof) 301 Page suspend resume ִ. ֶ󸮽 thr_suspend(), thr_continue() Լ Ѵ. -- //////////////////////////////////////////////////////////////*/ DWORD Suspend() { return ::SuspendThread(mh_ThreadID); }/* DWORD Suspend()*/ DWORD Resume() { return ::ResumeThread(mh_ThreadID); }/* DWORD Resume()*/ bool Close() { return ::CloseHandle(mh_ThreadID)==TRUE; }/* bool Close()*/ bool Detach() // for compatibility with linux { return true; }/* bool Detach()*/ public: };/* template< typename TTypeBase=ZNsIFace::ZCThread_BASE >/ class ZtCThread ////////////////////////////////////*/ template<> class ZtCThread { protected: ThreadID mh_ThreadID; public : ZtCThread() { _DEBUG_REENTRANT_CHECK_ mh_ThreadID = INVALID_HANDLE_VALUE ; }/* ZtCThread()*/ ZtCThread(const ZtCThread& rhs) { mh_ThreadID=rhs.mh_ThreadID; }/* ZtCThread(const ZtCThread& rhs)*/ ZtCThread& operator=(const ZtCThread& rhs) { return *this; }/* ZtCThread& operator=(const ZtCThread& rhs)*/ operator ThreadID () const { return mh_ThreadID; }/* operator ThreadID () const*/ ThreadID GetThreadID() const { return mh_ThreadID; }/* ThreadID GetThreadID() const*/ bool Make(LPTHREAD_START_ROUTINE AP_StartAddress, void* AP_Arg=0, DWORD dwCreationFlags=0, DWORD dwStackSize=0, LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL) { unsigned int VUI_ThreadID; return ( mh_ThreadID = (void*)::_beginthreadex ( lpThreadAttributes, dwStackSize, (unsigned int (__stdcall *)(void *))AP_StartAddress, AP_Arg, dwCreationFlags, &VUI_ThreadID ) /*****/ )!=INVALID_HANDLE_VALUE ; /////////////// #if 0 // CreateThread() Լ DWORD VUI_ThreadID; return ( mh_ThreadID = ::CreateThread ( lpThreadAttributes, dwStackSize, AP_StartAddress, AP_Arg, dwCreationFlags, &VUI_ThreadID ) /*****/ )!=INVALID_HANDLE_VALUE ; #endif }/* bool Make(LPTHREAD_START_ROUTINE AP_StartAddress, void* AP_Arg=0, DWORD dwCreationFlags=0, DWORD dwStackSize=0, LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL)*/ bool Make(unsigned (__stdcall *AP_StartAddress)(void *), void* AP_Arg=0, DWORD dwCreationFlags=0, DWORD dwStackSize=0, LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL) { unsigned int VUI_ThreadID; return ( mh_ThreadID=(void*)::_beginthreadex ( lpThreadAttributes , dwStackSize , AP_StartAddress , AP_Arg , dwCreationFlags , &VUI_ThreadID ) /*****/ )!=INVALID_HANDLE_VALUE ; ///////////// }/* bool Make(unsigned (__stdcall AP_StartAddress*)(void *), void* AP_Arg=0, DWORD dwCreationFlags=0, DWORD dwStackSize=0, LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL)*/ int Wait(DWORD ADW_MilliSeconds=INFINITE) { return ::WaitForSingleObject(mh_ThreadID, ADW_MilliSeconds); }/* int Wait(DWORD ADW_MilliSeconds=INFINITE)*/ static int Wait(ThreadID AI_ThreadIDVar, DWORD ADW_MilliSeconds=INFINITE) { return ::WaitForSingleObject(AI_ThreadIDVar, ADW_MilliSeconds); }/* static int Wait(ThreadID AI_ThreadIDVar, DWORD ADW_MilliSeconds=INFINITE)*/ bool Terminate(DWORD AI_ExitCode=0) { return ::TerminateThread(mh_ThreadID, AI_ExitCode)==TRUE; }/* bool Terminate(DWORD AI_ExitCode=0)*/ BOOL GetExitCode(DWORD& ARRDW_ExitCode) { return ::GetExitCodeThread(mh_ThreadID, &ARRDW_ExitCode); }/* BOOL GetExitCode(DWORD& ARRDW_ExitCode)*/ DWORD Suspend() { return ::SuspendThread(mh_ThreadID); }/* DWORD Suspend()*/ DWORD Resume() { return ::ResumeThread(mh_ThreadID); }/* DWORD Resume()*/ bool Close() { return ::CloseHandle(mh_ThreadID)==TRUE; }/* bool Close()*/ bool Detach() // for compatibility with linux { return true; }/* bool Detach()*/ public: };/* template<> class ZtCThread*/ /*/////////////////////////////////////////////////////////////////////////////// ȣ : 㰡ϴ ڵ ̺Ʈ : ° Ǹ ڵ ȣ ° ȴ. ̺Ʈ : 尡 ȣ · ȣ¸ Ѵ. SetEvent ̺Ʈ ȣ· , ResetEvent ̺Ʈ ȣ· . ( ٸ 尡 · .) ڵ ̺Ʈ 尡 WaitForSingleObject() ȣϸ ٸ SetEvent() Լ ̺Ʈ ȣ · Ȥ ðŭ ȴ. ̺Ʈ ټ 尡  ٸٰ Ǿ ϰ ϴ ִµ ǵ/ lock ̳ ؽ ִ. ε ִ. ټ 尡  ϰ ִٰ  Ǹ īƮ ŭ ÷ָ 尡  ̴.  ϴ , ( ׽Ʈغ ʾ) Window īƮ ϴ ŭ ÷־ 尡 ѹ  ʾҴ. īƮ 1 Ű ڵ带 ŭ ־ Ѵ. 2008-05-05 15:38:00 ///////////////////////////////////////////////////////////////////////////////*/ template class ZtCEvent : public TData { protected: ZTypeID mh_TypeID; public : /*////////////////////////////////////////////////////////////////////////////// CreateEvent() A handle to the event object indicates success. If the named event object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. NULL indicates failure. To get extended error information, call GetLastError. //////////////////////////////////////////////////////////////////////////////*/ bool Make(LPCTSTR AP_Name, BOOL AB_Reset=TRUE, BOOL AB_ManualReset=TRUE, LPSECURITY_ATTRIBUTES AP_SecAtt=NULL) { return (mh_TypeID = ::CreateEvent(AP_SecAtt, AB_Reset, AB_ManualReset, AP_Name))!=NULL; }/* bool Make(LPCTSTR AP_Name, BOOL AB_Reset=TRUE, BOOL AB_ManualReset=TRUE, LPSECURITY_ATTRIBUTES AP_SecAtt=NULL)*/ bool Set() const // ̺Ʈ ȣ· . { return ::SetEvent(mh_TypeID)==TRUE; }/* bool Set() const*/ bool Reset() const // ̺Ʈ ȣ· . { return ::ResetEvent(mh_TypeID)==TRUE; }/* bool Reset()*/ bool Pulse() const { return ::PulseEvent(mh_TypeID)==TRUE; /*////////////////////////////////////////////////////////////////////////////////////////////////////// ̺Ʈ SetEvent() Լ ȣϿ ̺Ʈ ȣ · . ׸ ϴ 尡 ¸  ٽ ڵ ̺Ʈ ȣ · ش. ׷ϱ ̺Ʈ ڵ ̺Ʈ ȿ ִ Լ̴. ׷ MSDN Ҿϱ ִ. http://msdn.microsoft.com/en-us/library/ms684914(VS.85).aspx Sets the specified event object to the signaled state and then resets it to the nonsignaled state after releasing the appropriate number of waiting threads. Note : This function is unreliable and should not be used. It exists mainly for backward compatibility. For more information, see Remarks. ϱ⸦ " ̺Ʈ ڵ ̺Ʈ ȿ ִ Լ̴." ߴµ ̰ Ʋ. ̺Ʈ ȣ · , ̺Ʈ ϴ 尡  Ȯ Ŀ ̺Ʈ ٽ ȣ · . ̺Ʈ ȣ · , Ʈ ϴ 尡  Ⱓ ؾ Ѵ. Ƹ κ ó Ҿ ϱ MSDN "unreliable" ̶ ̴. -- 2009-02-05 0:10:00 //////////////////////////////////////////////////////////////////////////////////////////////////////*/ }/* bool Pulse() const*/ int Wait(DWORD ADW_MilliSeconds=INFINITE) const { return ::WaitForSingleObject(mh_TypeID, ADW_MilliSeconds); }/* int Wait(DWORD ADW_MilliSeconds=INFINITE) const*/ /*////////////////////////////////////////////////////////////////////////////////////// ::WaitForSingleObject() ȯ WAIT_OBJECT_0 : The state of the specified object is signaled. WAIT_TIMEOUT : The time-out interval elapsed, and the object's state is nonsignaled. WAIT_FAILED : Fail Ʒ Lock 迭 Լ ƴϸ ZEThread_OK ZEThread_TimeOut ȯ ִ. //////////////////////////////////////////////////////////////////////////////////////*/ int Lock() const { return ::WaitForSingleObject(mh_TypeID, INFINITE); }/* int Lock() const*/ int LockRaw(DWORD ADW_MilliSeconds=INFINITE) const { return ::WaitForSingleObject(mh_TypeID, ADW_MilliSeconds); }/* int LockRaw(DWORD ADW_MilliSeconds=INFINITE) const*/ int LockTime(DWORD AI_TimeOutMili) { return LockRaw(AI_TimeOutMili); }/* int LockTime(DWORD AI_TimeOutMili)*/ bool UnLock() const // ̺Ʈ ȣ· . { return this->Set(); }/* bool UnLock()*/ public: };/* template class ZtCEvent */ template class ZtCBarrier : public TData { protected: ZTypeID mh_EventID; volatile LONG ml_BarrCnt; public : ZtCBarrier() { mh_EventID=0; ml_BarrCnt=0; }/* ZtCBarrier()*/ bool IsValid() const{return mh_EventID != 0 ; } /*///////////////////////////////////////////////////////////////////////////// Init() Fini() ȯ linux ȣȯ bool ƴϰ int ̴. ȯ ٷ if(CBarrierObj.Init(3)==ZNsEnum::ZEBarrier_OK) ̷ . Init() Լ ȣ ̺Ʈ . /////////////////////////////////////////////////////////////////////////////*/ int Init(unsigned AI_Count, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes=NULL, LPCTSTR AP_EventName=NULL) { if(AI_Count<1) AI_Count=1; ml_BarrCnt=AI_Count; /*//////////////////////////////////////////////////// ::CreateEvent() 3 μ : bInitialState If this parameter is TRUE, the initial state of the event object is signaled; otherwise, it is nonsignaled ////////////////////////////////////////////////////*/ if(mh_EventID!=0) return ::ResetEvent(mh_EventID)==TRUE; return (mh_EventID=::CreateEvent( ////////////////////// AP_SemaphoreAttributes , TRUE /*bManualReset */ , FALSE /*bInitialState*/ , AP_EventName) /*/////////*/ )!=(HANDLE)ERROR_INVALID_HANDLE ; //////// }/* int Init(unsigned AI_Count, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes=NULL, LPCTSTR AP_EventName=NULL)*/ int Fini() { bool VB_IsOK= (::CloseHandle(mh_EventID)==TRUE); mh_EventID=0; return VB_IsOK; }/* int Fini()*/ bool Wait() { if(::InterlockedDecrement(&ml_BarrCnt)>0) { return ::WaitForSingleObject(mh_EventID, INFINITE) != WAIT_FAILED; }/* if(::InterlockedDecrement(&ml_BarrCnt)>0)*/ return ::SetEvent(mh_EventID)==TRUE ; }/* bool Wait()*/ /*//////////////////////////////////////////////////////////////////////////////// LONG __cdecl InterlockedDecrement(__inout LONG volatile *Addend); Parameters : Addend [in, out] : A pointer to the variable to be decremented. Return Value : The function returns the resulting decremented value. The variable pointed to by the Addend parameter must be aligned on a 32-bit boundary; otherwise, this function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems. See _aligned_malloc. The interlocked functions provide a simple mechanism for synchronizing access to a variable that is shared by multiple threads. This function is atomic with respect to calls to other interlocked functions. This function is implemented using a compiler intrinsic where possible. For more information, see the Winbase.h header file and _InterlockedDecrement. This function generates a full memory barrier (or fence) to ensure that memory operations are completed in order. Provides compiler intrinsic support for the Win32 Platform SDK InterlockedDecrement function. long _InterlockedDecrement( long * lpAddend ); long _InterlockedDecrement_acq( long * lpAddend ); long _InterlockedDecrement_acq( long * lpAddend ); short _InterlockedDecrement16( short * lpAddend ); short _InterlockedDecrement16_acq( short * lpAddend ); short _InterlockedDecrement16_rel( short * lpAddend ); __int64 _InterlockedDecrement64( __int64 * lpAddend ); __int64 _InterlockedDecrement64_acq( __int64 * lpAddend ); __int64 _InterlockedDecrement64_rel( __int64 * lpAddend ); Parameters [in, out] lpAddend Pointer to the variable to be decremented. Return Value Windows 98, Windows NT 4.0, and later: The return value is the resulting decremented value. Windows 95, Windows NT 3.51, and earlier: If the result of the operation is zero, the return value is zero. If the result of the operation is less than zero, the return value is negative, but it is not necessarily equal to the result. If the result of the operation is greater than zero, the return value is positive, but it is not necessarily equal to the result. MSDN Ǵϸ InterlockedDecrement Լ _InterlockedDecrement~ 迭 SDK ϴµ ̵ SDK ' ҵ ȯ ʴ´' ִ. ̰ Լ LONG __cdecl InterlockedIncrement(__inout LONG volatile *Addend); ؼ ̴. ////////////////////////////////////////////////////////////////////////////////*/ public: };/* template< typename TData=ZNsMain::ZCEmpty > class ZtCBarrier ////////////////////////*/ /*/////////////////////////////////////////////////////////////////// ̿ؼ Ȱ ִ barrier Ŭ ø ZtCBarrier<> ټ ̴. event 2 Ѵ. ϳ Դ̰ ϳ 尡 Ǯ⸦ Ȯϴµ Ѵ. ׽Ʈ ̻ϰ lock ɸ ִ. ȭ ɶ . -- 2009-01-22 23:06:00 ///////////////////////////////////////////////////////////////////*/ template< typename TSyncExec=ZNsMain::ZCCriticSectEasy, typename TData =ZNsMain::ZCEmpty > class ZtCCondBarrier : public TData ///////////////////// { public : typedef ZNsMain::ZtCAutoKey CAutoKey; public : enum EStep { EStep_None, EStep_Init, EStep_Wait, EStep_Dead, EStep_Fini };/* enum EStep*/ /*public :*/ protected: TSyncExec mo_CSyncExec; ZTypeID mh_EventID ; ZTypeID mh_EWaitID ; // ϴ ̺Ʈ int mi_BarrCnt ; int mi_WaitCnt ; EStep me_EStep ; public : ZtCCondBarrier( LPCTSTR AP_EventName =NULL, LPCTSTR AP_EventName2=NULL, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes =NULL, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes2=NULL /*/////////*/ ) { me_EStep =EStep_None; mi_BarrCnt=0 ; mi_WaitCnt=0 ; mh_EventID=::CreateEvent( //////////////////// AP_SemaphoreAttributes , TRUE /*bManualReset*/ , FALSE /*bInitialState*/, AP_EventName /*/////////*/ ); ///////////////////////////// mh_EWaitID=::CreateEvent( //////////////////// AP_SemaphoreAttributes2 , TRUE /*bManualReset*/ , FALSE /*bInitialState*/ , AP_EventName2 /*/////////*/ ); ///////////////////////////// }/* ZtCCondBarrier( LPCTSTR AP_EventName =NULL, LPCTSTR AP_EventName2=NULL, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes =NULL, LPSECURITY_ATTRIBUTES AP_SemaphoreAttributes2=NULL ///////////// ) */ ~ZtCCondBarrier() { ::CloseHandle(mh_EventID); ::CloseHandle(mh_EWaitID); }/* ~ZtCCondBarrier()*/ EStep GetStep() const { return me_EStep; }/* EStep GetStep() const*/ bool IsValidID() const { return mh_EventID!=(HANDLE)ERROR_INVALID_HANDLE; }/* bool IsValidID() const*/ int Init(int AI_Count) { CAutoKey VO_CAutoKey(mo_CSyncExec); if(me_EStep!=EStep_None && me_EStep!=EStep_Fini) return ZNsEnum::ZEBarrier_NO; //endif if(AI_Count<1) AI_Count=1; mi_BarrCnt=AI_Count ; mi_WaitCnt=AI_Count ; me_EStep =EStep_Init; return ZNsEnum::ZEBarrier_OK; }/* int Init(int AI_Count)*/ bool Wait() { mo_CSyncExec.Lock(); if(me_EStep==EStep_Init) { me_EStep=EStep_Wait; } if(me_EStep!=EStep_Wait) { mo_CSyncExec.UnLock(); return false; }/* if(me_EStep!=EStep_Wait)*/ bool VB_IsOK=false; if(--mi_BarrCnt>0) { #ifdef _DEBUG cout<<" Wait Barrier : mi_BarrCnt="< Project -> Settings -> c/c++ -> Category -> Code Generation -> Use run-time library -> Ƽ ̺귯 Ͽ Ǵ, ɼǿ /MT, /MD, /MTd, /MDd ߿ ϳ Ѵ. /MT ũ /MD ũ /MTd ũ(DEBUG ) /MDd ũ(DEBUG ) -- ////////////////////////////////////////////////////////////////////////////*/ #endif //__ZCPPMAIN__PROCESS_WIN_H__