MFC中的工作线程终止

4

如果工作线程执行时间过长,正确的终止方式是什么?我读了几篇文章声称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

这样可以吗?欢迎收到所有的评论和建议。

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

2个回答

1

谢谢提供链接,我会逐一查看。 我想我应该说一下,从线程本身中终止它是很困难的,因为我正在调用一个已知会挂起的dll函数。我已经编辑了我的伪代码以反映这一点。 - House Sparrow
@House Sparrow 没问题,尽管问吧 :) - Sanja Melnichuk

1

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


谢谢回复。您能否再详细解释一下?LPC是指本地过程调用吗?当您说到子进程时,是指完全独立的.exe文件,而不是工作线程吗? - House Sparrow
是的,LPC指的是任何本地进程间通信(可以使用COM、共享内存、网络管道、WCF等实现)。通常,一个单独的进程是另一个.exe,但从技术上讲,它也可以是相同的.exe再次启动,只需使用不同的参数。最好是一个单独的.exe。 - Remus Rusanu
谢谢,这非常有帮助。 - House Sparrow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接