删除线程时崩溃

Crash when thread is deleted

本文关键字:崩溃 线程 删除      更新时间:2023-10-16

我正在使用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时)。

)。

线程终止其线程Proc并返回出口代码。

在我看来,这里有一个问题:

FileThread* FileThread::CreateWorkerThread(LPVOID params, UINT priority, 
                                           UINT flags)
{
    return (FileThread*) AfxBeginThread(FileThread::MyThreadProc, params, 
                                        priority, 0,  flags);
}

AfxBeginThread返回 CWinthread*,因此仅将其施放到您自己的派生类中并不能使其成为该派生类的实例。我很惊讶它完全有效。

而不是从CWinThread派生FileThread,而是在包装器类中持有CWinthread*成员变量,并在必要时通过访问器曝光线索。