李国帅 2012/1/4 10:08:19
在一个类中对接收的信息进行管理和分发:主要逻辑是,创建一个线程,从其他线程往这个线程中发送消息,然后这个线程对消息统一处理。
对象函数定义
HANDLE m_hThrdMsgHandle; //消息处理的线程
LONG m_nExit;
CComCriticalSection m_LockTag;
DWORD m_dwThreadIdMsgHandle;
LONG SetExitState(LONG nExit);
LONG GetExitState();
LONG CreateThreadMsgHandle();
LONG CloseThreadHandle();
static
启动
m_hThrdMsgHandle = NULL;
m_dwThreadIdMsgHandle = 0;
m_LockTag.Init();
SetExitState(0);
CreateThreadRecv();
关闭
CloseThreadHandle();
m_LockTag.Term();
停止标记
LONG CMessageMng::SetExitState(LONG nExit)
{
m_LockTag.Lock();
m_nExit = nExit;
m_LockTag.Unlock();
return 0;
}
LONG CMessageMng::GetExitState()
{
m_LockTag.Lock();
LONG nExit = m_nExit;
m_LockTag.Unlock();
return nExit;
}
处理线程
DWORD WINAPI CMessageMng::MsgHandleDataProc(LPVOID lpParam)
{
CMessageMng* pHandleMng = (CMessageMng*)lpParam;
MSG msg;//主消息循环:处理额外消息,比如客户端心跳,退出
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
while (GetMessage(&msg, NULL, 0, 0))
{
ATLASSERT(msg.message == 10000 || msg.message == WM_QUIT || (msg.message >= 0x0000c000 && msg.message <= 0x0000c7ff));//
if (msg.message == 10000)
{
LONG nMessageId = msg.wParam;
//pHandleMng->HandleNetCmdRecv(nMessageId);
}
else if (msg.message == WM_QUIT)
{
CModuleMng::Instance()->PrintfLog(LOG_INFO,"%s exit for WM_QUIT.",__FUNCTION__);
break;
}
if( pHandleMng->GetExitState() != 0)
{
CModuleMng::Instance()->PrintfLog(LOG_INFO,"%s exit for GetExitState() != 0.",__FUNCTION__);
break;
}
//Sleep(1);
}
return S_OK;
}
/*
BOOL bRet = FALSE;
LONG nMsgId = UMSG_LOGIN;
DWORD dwThreadId = m_pDataHandle->m_dwThreadIdRecv;
ATLASSERT(dwThreadId>0);
if(dwThreadId!=0)
{
LONG nTimes = 5;
while(nTimes-->0)
{
bRet = ::PostThreadMessage(dwThreadId,10000,nMsgId,0);
if (bRet)break;
}
}
ATLASSERT(bRet);
*/
创建线程
LONG CMessageMng::CreateThreadRecv()
{
if (m_hThrdMsgHandle != NULL) return 0;
m_hThrdMsgHandle = CreateThread(NULL, 0, MsgHandleDataProc, this, 0, &m_dwThreadIdMsgHandle);//播放视频
ATLASSERT(m_hThrdMsgHandle != NULL);
if(m_hThrdMsgHandle == NULL)
{
CModuleMng::Instance()->PrintfLog(LOG_INFO,"%s, CreateThread fail.",__FUNCTION__);
return -1;
}
CModuleMng::Instance()->PrintfLog(LOG_INFO,"%s, CreateThread OK.",__FUNCTION__);
return 0;
}
关闭线程
LONG CMessageMng::CloseThreadHandle()
{
SetExitState(1);
if (m_hThrdMsgHandle != NULL)
{
while(TRUE)
{
BOOL bRet = ::PostThreadMessage(m_dwThreadIdMsgHandle, WM_QUIT,0, 0);
ATLASSERT(bRet);
if (bRet)break;
}
HANDLE& hHandle = m_hThrdMsgHandle;
int nRetClose = CModuleMng::Instance()->CloseThreadHandle(hHandle);
if(nRetClose == 1)CModuleMng::Instance()->PrintfLog(LOG_INFO,"%s, TerminateThread. m_hThrdRecv \n",__FUNCTION__);
}
return 0;
}
等待线程关闭
LONG CModuleMng::CloseThreadHandle( HANDLE& hThrdHandle,LONG nWaitTime /*= 10000*/ )
{
//ATLASSERT(hThrdHandle != NULL);
if(hThrdHandle == NULL)return 0;//连接不存在
LONG nRet = -1;
HANDLE hThrd = hThrdHandle;
hThrdHandle = NULL;
int nRetCode = WAIT_TIMEOUT;
nRetCode = ::WaitForSingleObject(hThrd,nWaitTime);//等待线程结束
ATLASSERT(nRetCode != WAIT_TIMEOUT);
if(nRetCode == WAIT_TIMEOUT)
{
DWORD dwExitCode = 0;
::TerminateThread(hThrd,dwExitCode);
//PrintfLog(LOG_INFO,"%s, TerminateThread. hThrdHandle=%d \n",__FUNCTION__,hThrd);
SAFE_CLOSEHANDLE(hThrd);
nRet = 1;
}
else if (nRetCode == WAIT_OBJECT_0)
{
SAFE_CLOSEHANDLE(hThrd);
nRet = 0;
}
return nRet;
}