删除线程时崩溃
Posted
技术标签:
【中文标题】删除线程时崩溃【英文标题】:Crash when thread is deleted 【发布时间】:2014-01-20 13:59:15 【问题描述】:我正在使用 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 时)。
线程终止其线程过程并返回退出代码。
【问题讨论】:
【参考方案1】:在我看来这里有问题:
FileThread* FileThread::CreateWorkerThread(LPVOID params, UINT priority,
UINT flags)
return (FileThread*) AfxBeginThread(FileThread::MyThreadProc, params,
priority, 0, flags);
AfxBeginThread
返回一个CWinthread*
,因此仅将其转换为您自己的派生类不会使其成为该派生类的实例。我很惊讶它完全有效。
与其从CWinThread
派生FileThread
,不如在包装类中保存CWinthread*
成员变量并在必要时通过访问器公开线程句柄。
【讨论】:
下面的 MSDN 示例展示了如何正确地进行转换msdn.microsoft.com/en-us/library/z2h4xz23.aspx CWinthread 也有一个自动删除机制:msdn.microsoft.com/en-us/library/4bbe9bte.aspx @odedsh 嗯,有点像,它创建了一个 UI 线程,它有一个消息泵(需要用于套接字) - 它 可以 用作工作线程,但它可能是一个在许多情况下有点矫枉过正。 @Roger Rowland:这就是你认为的那种问题“当然,伙计!我有那么愚蠢吗?!” ;) 非常感谢,我将 CWinThread 包装在课堂上,一切正常。问题解决了以上是关于删除线程时崩溃的主要内容,如果未能解决你的问题,请参考以下文章