实际项目中,在主线程退出时,需要等待所有子线程完全退出之后主线程再退出,否则容易造成内存泄露。
首先,建立各工作者子线程,然后填充一下数组和参数:
m_handles[0]=pRawdata1Thread->m_hThread; // 填充线程句柄数组,用于等待子线程退出
m_handles[1]=pRawdata2Thread->m_hThread;
m_handles[2]=pResults1Thread->m_hThread;
m_handles[3]=pResults2Thread->m_hThread;
nWaitCount = 4; // 填充创建完成的子线程总数
其中,m_handles可以定义在主对话框类头文件中,作为一个成员变量:
HANDLE m_handles[4]; // 需要等待退出的子线程数组,这里要控制4个子线程,所以参数为4
然后,在主对话框类中添加一下函数,在主线程退出(如响应close消息)时调用该函数即可:
//***********************************************************************************************************************************
//函数名:void WaitThreadExit(int nWaitCount)
//功 能:主线程非阻塞模式下等待所有子线程退出。
//备 注:需要提前填写子线程句柄数组和需要退出的子线程总数。
//***********************************************************************************************************************************
void CDBConnectorDlg::WaitThreadExit(int nWaitCount)
{
DWORD dRet;
int nExitThreadCount=0; //标记已经有几个线程退出了
MSG msg;
BOOL bWaitAll=FALSE;
while (1)
{
dRet=MsgWaitForMultipleObjects(nWaitCount,m_handles,bWaitAll,INFINITE,QS_ALLINPUT);
if (dRet == WAIT_OBJECT_0+ nWaitCount)
{
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} }
else if (dRet >= WAIT_OBJECT_0 && dRet < WAIT_OBJECT_0+ nWaitCount)
{
nExitThreadCount++;
if (nExitThreadCount
{
int nIndex=dRet-WAIT_OBJECT_0;
m_handles[nIndex]=m_handles[nWaitCount-1];
m_handles[nWaitCount-1]=NULL;
nWaitCount--;
}
else
{
break;
}
}
else
{
DWORD dErrCode=GetLastError();
break;
}
}
}
注意文字红色部分的代码,这部分代码主要是实现用户自己处理消息循环;问题的提出是:当主线程通知子线程退出时,子线程可能需要操作对话框的控件;而此时如果主线程不对控件消息进行处理,则会造成死锁(主线程与子线程互相等待),程序无法退出。