356 lines
7.1 KiB
C++
356 lines
7.1 KiB
C++
#include "_osdef.h"
|
||
#include "Thread.h"
|
||
#include "stdio.h"
|
||
using namespace wylib::thread;
|
||
|
||
|
||
|
||
|
||
CBaseThread::CBaseThread(char *sThreadName,THREAD_CALLBACK callFun,void * pData)
|
||
{
|
||
m_hThread = 0;
|
||
m_dwThreadId = 0;
|
||
m_boWorking =0; //没有启动
|
||
m_boHasStoped =0; //是否已经停止完成了
|
||
//m_boTerminated = false;
|
||
|
||
m_callFun =callFun;
|
||
m_pCallBackData =pData;
|
||
|
||
if(sThreadName !=NULL)
|
||
{
|
||
strncpy(m_threadName,sThreadName,sizeof(m_threadName));
|
||
}
|
||
else
|
||
{
|
||
m_threadName[0]=0;
|
||
}
|
||
|
||
#ifdef WIN32
|
||
m_hWorkThreadEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); //等待线程启动事件发生
|
||
#else
|
||
m_boSuspend = false;
|
||
pthread_mutex_init(&m_Mutex, NULL);
|
||
pthread_cond_init(&m_Cond, NULL);
|
||
#endif
|
||
}
|
||
|
||
CBaseThread::~CBaseThread()
|
||
{
|
||
StopWorkThread();
|
||
|
||
#ifndef WIN32
|
||
pthread_mutex_destroy(&m_Mutex);
|
||
pthread_cond_destroy(&m_Cond);
|
||
#endif
|
||
|
||
}
|
||
|
||
THREAD_HANDLE CBaseThread::CreateThreadHandle(const DWORD dwFlags)
|
||
{
|
||
#ifdef WIN32
|
||
m_hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)ThreadRoutine, this, dwFlags, &m_dwThreadId);
|
||
#else
|
||
pthread_create(&m_hThread, NULL, ThreadRoutine, (void*)this);
|
||
//suspend();
|
||
m_dwThreadId = m_hThread;
|
||
printf("[thread%s-%u]create\n\r",m_threadName,(unsigned int)m_dwThreadId);
|
||
#endif
|
||
return m_hThread;
|
||
}
|
||
|
||
|
||
#ifdef WIN32
|
||
unsigned int CALLBACK CBaseThread::ThreadRoutine(void *lpThread)
|
||
{
|
||
if(lpThread ==NULL) return 0 ;
|
||
|
||
CBaseThread *pThread = (CBaseThread *)lpThread;
|
||
|
||
//唤醒线程
|
||
if(pThread->m_hWorkThreadEvent != INVALID_HANDLE_VALUE)
|
||
{
|
||
|
||
SetEvent(pThread->m_hWorkThreadEvent);
|
||
}
|
||
|
||
InterlockedCompareExchange(&pThread->m_boWorking, TRUE, FALSE );
|
||
pThread->OnThreadStarted();
|
||
|
||
//如果不传参数进来,则使用本身的继承的方式
|
||
if(pThread->m_callFun ==NULL)
|
||
{
|
||
|
||
while(pThread->m_boWorking)
|
||
{
|
||
pThread->OnRountine();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
while(pThread->m_boWorking )
|
||
{
|
||
pThread->m_callFun(pThread->m_pCallBackData); //调用
|
||
}
|
||
}
|
||
|
||
if(pThread)
|
||
{
|
||
pThread->OnTerminated();
|
||
|
||
SetEvent(pThread->m_hWorkThreadEvent); //让等待的人退出
|
||
InterlockedCompareExchange(&pThread->m_boHasStoped, TRUE, FALSE ); //表示已经停止了
|
||
}
|
||
|
||
|
||
ExitThread(0);
|
||
return 0;
|
||
}
|
||
#else
|
||
void * CBaseThread::ThreadRoutine(void * lpThread)
|
||
{
|
||
if(lpThread ==NULL) return 0;
|
||
CBaseThread *pThread = (CBaseThread *)lpThread;
|
||
char * sName = pThread->m_threadName;
|
||
unsigned int nThreadId = pThread->m_dwThreadId;
|
||
|
||
printf("[thread %s-%u] ThreadRoutine\n\r",sName,nThreadId);
|
||
|
||
//唤醒母线程
|
||
pthread_mutex_t * pMutex = &( pThread->m_Mutex);
|
||
pthread_cond_t * pCond = &( pThread->m_Cond);
|
||
|
||
pthread_mutex_lock(pMutex);
|
||
pthread_cond_signal(pCond);
|
||
pthread_mutex_unlock(pMutex);
|
||
|
||
InterlockedCompareExchange(&pThread->m_boWorking, TRUE, FALSE );
|
||
pThread->OnThreadStarted();
|
||
if(pThread->m_callFun ==NULL)
|
||
{
|
||
while(pThread->m_boWorking)
|
||
{
|
||
pThread->OnRountine();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
while(pThread->m_boWorking)
|
||
{
|
||
pThread->m_callFun(pThread->m_pCallBackData); //调用
|
||
}
|
||
}
|
||
pThread->OnTerminated();
|
||
|
||
pMutex = &( pThread->m_Mutex);
|
||
pCond = &( pThread->m_Cond);
|
||
|
||
pthread_mutex_lock(pMutex);
|
||
pthread_cond_signal(pCond);
|
||
pthread_mutex_unlock(pMutex);
|
||
InterlockedCompareExchange(&pThread->m_boHasStoped, TRUE, FALSE ); //表示已经停止了
|
||
|
||
printf("[thread %s-%u]exit\n\r",sName,nThreadId);
|
||
//InterlockedCompareExchange(&pThread->m_boWorking, FALSE, TRUE );
|
||
|
||
pthread_exit(0);
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
void CBaseThread::OnRountine()
|
||
{
|
||
}
|
||
|
||
|
||
|
||
void CBaseThread::OnSuspend(int nSuspendCount)
|
||
{
|
||
}
|
||
|
||
void CBaseThread::OnResume(int nSuspendCount)
|
||
{
|
||
}
|
||
|
||
void CBaseThread::OnTerminated()
|
||
{
|
||
}
|
||
|
||
int CBaseThread::suspend()
|
||
{
|
||
|
||
int dwSuspended;
|
||
#ifdef WIN32
|
||
dwSuspended = SuspendThread( m_hThread );
|
||
#else
|
||
if(m_boSuspend ) return -1;
|
||
pthread_mutex_lock(&m_Mutex);
|
||
m_boSuspend =true;
|
||
dwSuspended = pthread_cond_wait(&m_Cond, &m_Mutex);
|
||
pthread_mutex_unlock(&m_Mutex);
|
||
|
||
#endif
|
||
if ( dwSuspended != -1 )
|
||
{
|
||
OnSuspend(dwSuspended + 1);
|
||
return dwSuspended + 1;
|
||
}
|
||
return dwSuspended;
|
||
}
|
||
|
||
int CBaseThread::resume()
|
||
{
|
||
printf("[thread %s-%u]resume\n\r",m_threadName,(unsigned int)m_dwThreadId);
|
||
int dwSuspended;
|
||
#ifdef WIN32
|
||
dwSuspended = ResumeThread( m_hThread );
|
||
#else
|
||
|
||
pthread_mutex_lock(&m_Mutex);
|
||
m_boSuspend =false;
|
||
dwSuspended = pthread_cond_signal(&m_Cond);
|
||
pthread_mutex_unlock(&m_Mutex);
|
||
|
||
printf("[thread %s-%u]resume end\n\r",m_threadName,(unsigned int)m_dwThreadId);
|
||
|
||
#endif
|
||
if ( dwSuspended != -1 )
|
||
{
|
||
OnResume(dwSuspended - 1);
|
||
return dwSuspended - 1;
|
||
}
|
||
return dwSuspended;
|
||
}
|
||
|
||
int CBaseThread::getPriority()
|
||
{
|
||
#ifdef WIN32
|
||
return GetThreadPriority( m_hThread );
|
||
#else
|
||
return getpriority(PRIO_PROCESS, m_dwThreadId);
|
||
#endif
|
||
}
|
||
|
||
bool CBaseThread::setPriority(int nPriority)
|
||
{
|
||
#ifdef WIN32
|
||
return SetThreadPriority( m_hThread, nPriority ) != 0;
|
||
#else
|
||
return setpriority(PRIO_PROCESS, m_dwThreadId, nPriority);
|
||
#endif
|
||
}
|
||
|
||
int CBaseThread::waitFor(DWORD dwWaitLong, bool boWaitAlertAble)
|
||
{
|
||
if(FALSE== InterlockedCompareExchange(&m_boHasStoped, FALSE, FALSE) ) //如果引擎已经启动得话
|
||
{
|
||
|
||
#ifdef WIN32
|
||
return WaitForSingleObjectEx( m_hWorkThreadEvent, dwWaitLong, boWaitAlertAble );
|
||
#else
|
||
return pthread_join(m_hThread, NULL); //等待一个线程的结束
|
||
#endif
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void CBaseThread::terminate()
|
||
{
|
||
InterlockedCompareExchange(&m_boWorking, FALSE, TRUE); //
|
||
|
||
}
|
||
|
||
// 开始工作,创建工作线程发送数据
|
||
void CBaseThread::StartWorkThread()
|
||
{
|
||
if( m_hThread !=0 )return;
|
||
|
||
if( CreateThreadHandle( 0 ) <=0 ) //创建线程失败
|
||
{
|
||
printf("Create thread %s Fail",m_threadName);
|
||
return;
|
||
}
|
||
printf("Start thread id=%d\n",(int)m_hThread);
|
||
|
||
//如果线程还没有启动完成,需要等待一段时间
|
||
if(FALSE== InterlockedCompareExchange(&m_boWorking, FALSE, FALSE) ) //如果引擎已经启动得话
|
||
{
|
||
|
||
#ifdef WIN32
|
||
if(m_hWorkThreadEvent != INVALID_HANDLE_VALUE)
|
||
{
|
||
if( WAIT_TIMEOUT == WaitForSingleObject(m_hWorkThreadEvent, 300000) ) //等待工作线程启动,等待5秒,如果没启动工作线程的话
|
||
{
|
||
printf("Create thread time out");
|
||
}
|
||
ResetEvent(m_hWorkThreadEvent);
|
||
}
|
||
#else
|
||
struct timespec nowTimer;
|
||
nowTimer.tv_sec = time(NULL) +5;
|
||
nowTimer.tv_nsec=0;
|
||
pthread_mutex_lock(&m_Mutex);
|
||
//dwSuspended = pthread_cond_wait(&m_Cond, &m_Mutex);
|
||
//这里不使用长等待,使用限时的等待,避免线程启动失败,把母线程卡死的现象
|
||
int ret= pthread_cond_timedwait(&m_Cond,&m_Mutex,&nowTimer ); //等待5秒钟看效果
|
||
if(ret == ETIMEDOUT)
|
||
{
|
||
printf("Create thread time out");
|
||
}
|
||
pthread_mutex_unlock(&m_Mutex);
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
#ifdef WIN32
|
||
if(m_hWorkThreadEvent != INVALID_HANDLE_VALUE)
|
||
{
|
||
if(m_hWorkThreadEvent != INVALID_HANDLE_VALUE)
|
||
{
|
||
ResetEvent(m_hWorkThreadEvent);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
}
|
||
|
||
|
||
// 停止工作线程发送数据
|
||
void CBaseThread::StopWorkThread()
|
||
{
|
||
if(FALSE== InterlockedCompareExchange(&m_boWorking, FALSE, FALSE) )
|
||
{
|
||
|
||
}
|
||
else
|
||
{
|
||
terminate();
|
||
waitFor(300000);
|
||
printf("Stop thread id=%d",(int)m_hThread);
|
||
if ( m_hThread )
|
||
{
|
||
#ifdef WIN32
|
||
if(m_hThread != INVALID_HANDLE_VALUE)
|
||
{
|
||
CloseHandle( m_hThread );
|
||
}
|
||
#else
|
||
//pthread_mutex_destroy(&m_Mutex);
|
||
//pthread_cond_destroy(&m_Cond);
|
||
#endif
|
||
m_hThread = 0;
|
||
m_boWorking =FALSE;
|
||
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
|