最近得项目使用一个对话框做为界面,内部数据处理使用线程。但是,在调试状态下,点击退出或者关闭对话框时,会提示有一个(CWinThread*)类型变量的68个字节的内存泄漏。
该线程的使用模型如下。程序打开后,使用AfxBeginThread(MyControllingFunction, NULL, 0, 0, NULL)建立一个工作者线程。其响应函数为
UINT MyControllingFunction( LPVOID pParam )
{
while(1)
{
// ......
}
}
AfxBeginThread返回一个(CWinThread*)类型的指针。
这个时候,该工程其实有两个线程在运行。一个是主线程,另一个就是这个工作者线程。问题就是有此带来的。在主线程退出时,工作者线程依然在运行。当然,在工程退出时,操作系统自动关闭了这个工作者线程。
解决这个问题的关键就是怎么样保证工作者线程在主线程之前退出。
首先,用一个BOOL类型的变量m_bIsValid改造MyControllingFunction中的死循环。m_bIsValid在建立线程之前赋TRUE,MyControllingFunction中的死循环改为
while(m_bIsValid)
{
// ......
}
那么怎么样才可以在关闭对话框时赋m_bIsValid=FALSE呢?由于基于对话框的工程对话框dlg类是没有析构函数的,所以必须手动添加一个dlg类的析构函数。在析构函数中,赋m_bIsValid=FALSE。
可是,这样大多数情况下还是有内存泄漏的提示存在。这是由于主线程太快了!那么,第二步的关键就是怎么样让主线程稍微等待工作者线程退出了。这个就是小菜一碟了。可以使用信号量对象。
1 在建立工作者线程的之前建立一个信号量m_hEventExitDlg = CreateEvent(NULL,TRUE,FALSE,NULL),这个信号量初始是没有信号的。
2 在MyControllingFunction中的循环之后使用SetEvent(m_hEventExitDlg)将这个信号量置为有信号。
3 在析构函数中的m_bIsValid=FALSE之后,使用WaitForSingleObject(m_hEventExitDlg, INFINITE)等待这个信号量。
4 在WaitForSingleObject之后,用CloseHandle(m_hEventExitDlg)关闭这个信号量。使用这个方法后,也可以将其它需要释放的资源在此释放,保证工作者线程不会访问主线程已经释放的资源。
这样就确保工作者线程在主线程之前退出了。