【问题标题】:Worker thread termination in MFCMFC 中的工作线程终止
【发布时间】:2011-10-27 08:25:56
【问题描述】:

如果工作线程完成时间过长,终止工作线程的正确方法是什么?我已经阅读了几篇文章,声称应极其谨慎地使用 TerminateThread,但我找不到任何可行的替代方案。

伪代码:

void CMyDialog::RunThread()
{
    CWinThread* pThread;            // pointer to thread
    DWORD dwWaitResult;             // result of waiting for thread


    // start thread
    pThread = AfxBeginThread(beginThread, this, 
                           THREAD_PRIORITY_NORMAL, 
                           0,     
                           CREATE_SUSPENDED);
    pThread->m_bAutoDelete = FALSE;
    pThread->ResumeThread();

    // wait for thread to return
    dwWaitResult = ::WaitForSingleObject(pThread->m_hThread, (30 * 1000)); 

    switch (dwWaitResult) 
    {
        case WAIT_OBJECT_0: 

            delete pThread;

            // success, continue

            break;

        case WAIT_TIMEOUT: 

            // thread taking too long, terminate it
            TerminateThread(pThread->m_hThread, 0);
            delete pThread;

            break;

    } // end switch on wait result


} 


UINT CMyDialog::beginThread(LPVOID pParam)
{
    // convert parameter back to dialog object and call method
    CMyDialog* dlg = (CMyDialog*) pParam;
    dlg->readDuration();

    return 0;
} // end beginThread


void CMyDialog::readDuration()
{
    // call a dll function that may take longer than we are prepared to wait, 
    // or even hang

} // end readDuration

这可以接受吗?非常感谢所有 cmets 和建议。

我在 Visual Studio 2008 中使用 MFC/C++。在 Vista 上开发,针对 XP、Vista 和 7。

【问题讨论】:

    标签: multithreading mfc waitforsingleobject


    【解决方案1】:

    使用 TerminateThread 是个坏主意,它不安全并且可能导致一些泄漏。您可以使用事件来告诉您的线程结束。 一些有用的链接

    1. http://www.codeproject.com/KB/threads/Synchronization.aspx

    2. http://msdn.microsoft.com/en-us/library/ms686915(v=vs.85).aspx

    关于终止线程here的好答案

    【讨论】:

    • 感谢您提供的链接,我会努力解决的。我想我应该说很难从线程本身中终止,因为我正在调用一个已知会挂起的 dll 函数。我已经编辑了我的伪代码以反映这一点。
    • @House Sparrow 没问题,请问:)
    【解决方案2】:

    正如 Sanja 已经提到的,终止线程是不安全的。在这种情况下,典型的解决方案是生成一个子进程,其唯一作用是托管 DLL 并调用方法。您的主进程将通过一些 LPC 机制与子进程通信,以传递 DLL 方法调用的参数并返回结果。在超时时杀死子进程是完全安全的,内核将回收所有资源,并且不会有内存或系统对象泄漏(可能存在持久的磁盘泄漏,例如遗留的文件)。它比仅仅调用 DLL 复杂得多(您需要提出进程间通信解决方案),但这是唯一可靠的方法。

    【讨论】:

    • 感谢您的回复。你能再解释一下吗? LPC是指本地过程调用吗?当您谈论子进程时,您是指完全独立的 exe 而不是工作线程?
    • 是的,LPC 指的是任何本地进程间通信(可以使用 COM、共享内存、网络管道、WCF 等实现)。一个单独的进程通常是另一个 .exe,但从技术上讲,它可能是再次启动的同一个 .exe,但参数不同。最好是一个单独的.exe
    • 谢谢,这对您很有帮助。
    猜你喜欢
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多