2011-08-15 54 views
4

如果工作線程完成時間過長,終止工作線程的正確方法是什麼?我讀過幾篇文章,強調應該非常謹慎地使用TerminateThread,但是我找不到任何可行的選擇。MFC中的工作線程終止

Psudo代碼:

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 

這是可以接受的?感謝所有意見和建議。

我使用MFC/C++在Visual Studio 2008上Vista的開發,針對XP,Vista和7

回答

1

是不安全的終止線程,如莎娜已經提到。在這種情況下,典型的解決方案是生成一個子進程,只有角色承載DLL並調用方法。您的主進程將通過一些LPC機制與子進程進行通信,以傳遞DLL方法調用的參數並返回結果。超時是非常安全的殺死子進程,內核將回收所有資源,並且不會有內存或系統對象泄漏(可能會持續存在磁盤泄漏,但剩下的文件)。只是簡單地調用DLL(你需要提出進程間通信解決方案),但這是唯一可靠的方法,這顯得更加複雜。

+0

感謝您的回覆。你能解釋一下嗎?通過LPC你是指本地程序調用?當你談論一個子進程時,你的意思是一個完全獨立的exe文件,而不是一個工作線程? –

+0

是的,通過LPC,我的意思是任何本地進程間通信(可以使用COM,共享內存,網管,WCF等來實現)。一個單獨的進程通常是另一個.exe,但從技術上講它可能是相同的.exe再次啓動,具有不同的參數。最好是單獨的.exe –

+0

謝謝,這是最有幫助的。 –

1

它是一個壞主意,使用TerminateThread它不是安全的,並可能導致一些泄漏。你可以使用事件來告訴你的線程結束。 一些有用的鏈接

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

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

好回答有關terminatethread here

+0

感謝您的鏈接,我會通過他們的方式工作。 我想我應該說,從線程內部很難終止,因爲我調用了一個已知掛起的dll函數。我編輯了我的僞代碼以反映這一點。 –

+0

@House Sparrow沒問題,只是問:) –