📄 thread.cpp
字号:
// //------------------------------------------------------------------------------bool C_Thread::operator == (const C_Thread& cThread){#ifdef PTHREAD_COND_T_IN_PTHREAD_H return (this->tId == cThread.tId);#elif defined WIN32 return (this->hThread == cThread.hThread);#endif};//------------------------------------------------------------------------------// Return the identifier of the calling thread//-----------------------------------------------------------------------------// The result can be NULL if the calling thread has not been created through// a C_Thread::Create (eg: the main thread, launched with the process)// TO DO: create an iterator on lists an use it, it would be really faster//-----------------------------------------------------------------------------C_Thread* C_Thread::Self(){ C_Thread* pResult = NULL;#ifdef PTHREAD_COND_T_IN_PTHREAD_H pthread_t tId = pthread_self(); for(unsigned int i = 0; i < s_cThreadList.Size(); i++) { C_Thread& cCurrent = s_cThreadList[i]; if(cCurrent.tId == tId) { pResult = &cCurrent; break; } }#elif defined _WIN32 HANDLE hThread = GetCurrentThread(); for(unsigned int i = 0; i < s_cThreadList.Size(); i++) { C_Thread& cCurrent = s_cThreadList[i]; if(cCurrent.hThread == hThread) { pResult = &cCurrent; break; } }#endif return pResult;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------bool C_Thread::IsRunning() const{ return (m_iStatus == THREAD_STATUS_STARTED);}//------------------------------------------------------------------------------////------------------------------------------------------------------------------// The purpose of this routine is only to allow the "extern C" pthread_create// functions to call the DoWork() C++ method//------------------------------------------------------------------------------void* C_Thread::StartRoutine(void* pThread){ C_Thread* pThis = (C_Thread*)pThread; E_Exception* p_eError = NULL; pThis->m_iStatus = THREAD_STATUS_STARTED; try { pThis->DoWork(); } catch(E_Exception e) { p_eError = new E_Exception(e); } pThis->m_iStatus = THREAD_STATUS_STOPPED; return p_eError;}//******************************************************************************// Class C_Mutex//******************************************************************************////******************************************************************************//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_Mutex::C_Mutex(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_mutex_init(&m_sMutex, NULL); ASSERT(!iRc); // The function shouldn't fail USE(iRc);#elif defined _WIN32 InitializeCriticalSection( &m_sMutex );#endif }//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_Mutex::~C_Mutex(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_mutex_destroy(&m_sMutex); ASSERT(!iRc); // The mutex should not be locked when being destroyed USE(iRc);#elif defined _WIN32 DeleteCriticalSection( &m_sMutex );#endif}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Mutex::Lock(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_mutex_lock(&m_sMutex); ASSERT(!iRc); // Errors only happen with bad uses of the mutex USE(iRc);#elif defined _WIN32 EnterCriticalSection( &m_sMutex );#endif }//------------------------------------------------------------------------------// //------------------------------------------------------------------------------void C_Mutex::UnLock(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_mutex_unlock(&m_sMutex); ASSERT(!iRc); // Errors only happen with bad uses of the mutex USE(iRc);#elif defined _WIN32 LeaveCriticalSection( &m_sMutex );#endif }//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// If the mutex is not locked, lock it and return NO_ERR, otherwise returns// immediatly MUTEX_LOCKED//------------------------------------------------------------------------------int C_Mutex::TryLock(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_mutex_trylock(&m_sMutex); if(iRc == EBUSY) return MUTEX_LOCKED; else { ASSERT(iRc == 0); return NO_ERR; }#elif defined _WIN32 ASSERT(false); return GEN_ERR;#endif}//******************************************************************************// Class C_Semaphore//******************************************************************************////******************************************************************************//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_Semaphore::C_Semaphore(unsigned int iInitialValue){#ifdef PTHREAD_COND_T_IN_PTHREAD_H# ifdef USE_SEM_T int iRc = sem_init(&sSemaphore, 0, iInitialValue); ASSERT(!iRc) // Should never fail USE(iRc);# else pthread_mutex_init(&m_sMutex, NULL); pthread_cond_init(&m_sCondition, NULL); sSemaphore = iInitialValue;# endif#elif defined _WIN32 sSemaphore = CreateSemaphore(NULL, iInitialValue, 32767, NULL);#endif }//------------------------------------------------------------------------------// //------------------------------------------------------------------------------C_Semaphore::~C_Semaphore(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H# ifdef USE_SEM_T int iRc = sem_destroy(&sSemaphore); ASSERT(!iRc); // No thread should be waiting on it at that time USE(iRc);# else pthread_mutex_destroy(&m_sMutex); pthread_cond_destroy(&m_sCondition);# endif#elif defined _WIN32 CloseHandle(sSemaphore);#endif}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Semaphore::Post(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H# ifdef USE_SEM_T return sem_post(&sSemaphore);# else pthread_mutex_lock(&m_sMutex); sSemaphore++; pthread_cond_signal(&m_sCondition); pthread_mutex_unlock(&m_sMutex); return 0;# endif#elif defined _WIN32 return ReleaseSemaphore(sSemaphore, 1, NULL);#endif }//------------------------------------------------------------------------------// //------------------------------------------------------------------------------int C_Semaphore::Wait(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H# ifdef USE_SEM_T return sem_wait(&sSemaphore);# else pthread_mutex_lock(&m_sMutex); while (!sSemaphore) { pthread_cond_wait(&m_sCondition, &m_sMutex); } sSemaphore--; pthread_mutex_unlock(&m_sMutex); return 0;# endif#elif defined _WIN32 return WaitForSingleObject(sSemaphore, INFINITE);#endif}//******************************************************************************// Class C_Condition//******************************************************************************////******************************************************************************//------------------------------------------------------------------------------////------------------------------------------------------------------------------C_Condition::C_Condition(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_mutex_init(&m_sMutex, NULL); ASSERT(!iRc); // The function shouldn't fail iRc = pthread_cond_init(&m_sCondition, NULL); ASSERT(!iRc);#elif defined _WIN32 InitializeCriticalSection( &m_sMutex ); /* initialise counter */ m_iWaitingThreads = 0; /* Create an auto-reset event. */ m_sSignal = CreateEvent(NULL, /* no security */ FALSE, /* auto-reset event */ FALSE, /* non-signaled initially */ NULL); /* unnamed */ //ASSERT (!m_sSignal);#endif}//------------------------------------------------------------------------------////------------------------------------------------------------------------------C_Condition::~C_Condition(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_mutex_destroy(&m_sMutex); ASSERT(!iRc); // The mutex should not be locked when being destroyed iRc = pthread_cond_destroy(&m_sCondition); ASSERT(!iRc); // No thread should wait on the condition #elif defined _WIN32 DeleteCriticalSection( &m_sMutex );#endif}//------------------------------------------------------------------------------////------------------------------------------------------------------------------void C_Condition::Protect(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_mutex_lock(&m_sMutex); ASSERT(!iRc); USE(iRc);#elif defined _WIN32 EnterCriticalSection( &m_sMutex );#endif}//------------------------------------------------------------------------------////------------------------------------------------------------------------------void C_Condition::Release(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_mutex_unlock(&m_sMutex); ASSERT(!iRc); USE(iRc);#elif defined _WIN32 LeaveCriticalSection( &m_sMutex );#endif}//------------------------------------------------------------------------------////------------------------------------------------------------------------------void C_Condition::Signal(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_cond_signal(&m_sCondition); ASSERT(!iRc); iRc = pthread_mutex_unlock(&m_sMutex); ASSERT(!iRc);#elif defined _WIN32 int iWaitingThreads = m_iWaitingThreads; while (m_iWaitingThreads && m_iWaitingThreads == iWaitingThreads) { PulseEvent (m_sSignal); Sleep (0); // deschedule the current thread }#endif}//------------------------------------------------------------------------------////------------------------------------------------------------------------------void C_Condition::Broadcast(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_cond_broadcast(&m_sCondition); ASSERT(!iRc); iRc = pthread_mutex_unlock(&m_sMutex); ASSERT(!iRc);#elif defined _WIN32 while (m_iWaitingThreads) { PulseEvent( m_sSignal ); Sleep( 0 ); // deschedule the current thread }#endif}//------------------------------------------------------------------------------////------------------------------------------------------------------------------void C_Condition::Wait(){#ifdef PTHREAD_COND_T_IN_PTHREAD_H int iRc = pthread_cond_wait(&m_sCondition, &m_sMutex); ASSERT(!iRc); USE(iRc);#elif defined _WIN32 m_iWaitingThreads ++; // Release the mutex LeaveCriticalSection( &m_sMutex ); WaitForSingleObject( m_sSignal, INFINITE); // maybe we should protect this with a mutex ? m_iWaitingThreads --; // Reacquire the mutex before returning. EnterCriticalSection( &m_sMutex );#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -