我正在使用 MFC 开发一个应用程序。 UI 线程启动一个工作线程并在应用程序关闭时停止它。问题是应用程序每次尝试删除线程时都会崩溃。
这是代码:
首先是线程类及其实现:
class FileThread : public CWinThread
{
public:
static FileThread* CreateWorkerThread(LPVOID params, UINT priority, UINT flags);
void InitThread();
void StopThread();
inline HANDLE GetStopHandle() const { return m_stopThread; }
inline HANDLE GetWaitHandle() const { return m_waitThread; }
private:
HANDLE m_stopThread;
HANDLE m_waitThread;
FileThread(): m_stopThread(NULL), m_waitThread(NULL) { }
static UINT MyThreadProc(LPVOID pParam);
};
FileThread* FileThread::CreateWorkerThread(LPVOID params, UINT priority, UINT flags)
{
return (FileThread*) AfxBeginThread(FileThread::MyThreadProc, params, priority, 0, flags);
}
void FileThread::InitThread()
{
m_stopThread = CreateEvent(0, TRUE, FALSE, 0);
m_waitThread = CreateEvent(0, TRUE, FALSE, 0);
}
void FileThread::StopThread()
{
::SetEvent(m_stopThread);
::WaitForSingleObject(m_waitThread, INFINITE);
::CloseHandle(m_stopThread);
::CloseHandle(m_waitThread);
}
UINT FileThread::MyThreadProc(LPVOID pParam)
{
ThreadData* pLink = (ThreadData*)pParam;
BOOL continueProcess = TRUE;
int returnCode = EXITCODE_SUCCESS;
while (continueProcess)
{
if(::WaitForSingleObject(pLink->pMe->GetStopHandle(), 0) == WAIT_OBJECT_0)
{
::SetEvent(pLink->pMe->GetWaitHandle());
continueProcess = FALSE;
}
// the thread is looking for some files...
}
delete pLink; // it was allocated from the UI thread
return returnCode;
}
然后,我开始线程的地方:
ThreadData * td = new ThreadData();
m_myFileThread = FileThread::CreateWorkerThread((LPVOID)td, THREAD_PRIORITY_LOWEST, CREATE_SUSPENDED);
td->pMe = m_myFileThread;
m_myFileThread->m_bAutoDelete = FALSE;
m_myFileThread->InitThread();
m_myFileThread->ResumeThread();
最后,停止(和崩溃):
DWORD exitCode;
if (m_myFileThread != NULL && GetExitCodeThread(m_myFileThread->m_hThread, &exitCode) && (exitCode == STILL_ACTIVE))
{
m_myFileThread->StopThread();
if(::WaitForSingleObject(m_myFileThread->m_hThread, 5000) == WAIT_TIMEOUT)
{
TerminateThread(m_myFileThread->m_hThread, EXITCODE_ABORT);
}
}
if (m_myFileThread != NULL)
{
delete m_myFileThread; // => CRASH
}
我似乎尝试删除已删除的内容,但最终导致堆损坏。我尝试将 m_bAutoDelete 设置为 TRUE,而不是自己删除线程,因为我遇到了相同的崩溃(当程序尝试调用 AfxEndThread 时)。
线程终止其线程过程并返回退出代码。
最佳答案
在我看来这里有问题:
FileThread* FileThread::CreateWorkerThread(LPVOID params, UINT priority,
UINT flags)
{
return (FileThread*) AfxBeginThread(FileThread::MyThreadProc, params,
priority, 0, flags);
}
AfxBeginThread
返回一个 CWinthread*
,因此仅将其转换为您自己的派生类不会使其成为该派生类的实例。我很惊讶它居然能起作用。
与其从 CWinThread
派生 FileThread
,不如在包装类中保存 CWinthread*
成员变量并公开线程如有必要,通过访问器进行处理。
关于c++ - 删除线程时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21235962/