[英]MFC Worker Thread Not Cleaning Up On Unexpected Shutdown
x64 ... VS2015 ...在函数内部,我这样调用线程:
CString* arr = new CString("test");
CWinThread *pThread;
if(!(pThread->AfxBeginThread(ThreadProc, (LPVOID)arr))) {
delete arr;
}
对于Proc:
UINT ThreadProc(LPVOID pParam) {
CString* InputString = (CString*)pParam;
delete InputString;
return 0;
}
如果线程正常完成,它会清理得很好,但是如果在线程运行时应用程序关闭,它将导致内存泄漏。 在VS2008下,调试未在VS2015下检测到任何泄漏。 从那以后,MFC清理线程的方式发生了变化吗?
PROC:
UINT ThreadProc(LPVOID pParam) {
CMainFrame* pMainFrm = (CMainFrame*)AfxGetApp()->m_pMainWnd;
while(!pMainFrm->m_threadcancelflag ){
}
return 0;
}
在标题中:
HANDLE hThread;
BOOL m_shutdownflag;
volatile BOOL m_threadcancelflag;
在源中:
CWinThread *pThread;
if(!(pThread = AfxBeginThread(ThreadProc, (LPVOID)arr, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED))) {
delete arr;
}
else{
::DuplicateHandle(GetCurrentProcess(), pThread->m_hThread, GetCurrentProcess(), &hThread, 0, FALSE, DUPLICATE_SAME_ACCESS);
pThread->ResumeThread();
}
替代WM_CLOSE:
void CMainFrame::OnClose() {
DWORD dwExitCode;
if(hThread){
::GetExitCodeThread(hThread, &dwExitCode);
if (dwExitCode == STILL_ACTIVE) {
if(!m_shutdownflag){
m_shutdownflag = TRUE;
if (AfxMessageBox(_T("Running Process. \n\nQuitting now may result in a loss of data and/or incomplete database tables.\n\nTo quit anyway click \"OK\"\nTo allow the process to complete normally click \"Cancel\"."), MB_ICONSTOP | MB_OKCANCEL) == IDCANCEL) {
m_shutdownflag = FALSE;
return;
}
else {
m_shutdownflag = TRUE;
}
}
m_threadcancelflag = TRUE;
Sleep(500);
PostMessage(WM_CLOSE);
}
else {
::CloseHandle(hThread);
}
}
CFrameWndEx::OnClose();
}
编辑:这是一个完整的解决方案...据记录,这是一个糟糕的程序员,他没有预见到意外情况,而是编写了一个程序,该程序在执行完后并不会自行清理,而是依赖于操作系统来执行程序应具有的功能完成。 良好的编程习惯包括添加错误和异常处理以及自行清除。 垃圾收集是编程的基础,即使在理想情况下结束程序很容易,但如果不是,则要多花些钱,但是良好的编程习惯表明您必须始终预见到意外情况。 我希望这段代码对其他人有帮助。 无论程序如何结束,此代码都不会由于正在进行的线程而导致内存泄漏。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.