2009-06-17 77 views
2

大家好,如何正確地終止dll內的掛線?

我有一個第三方庫,其中包含一個錯誤。當我調用一個函數時,它可能會掛起。庫函數在DLL中調用。我決定將電話轉入線程並等待一段時間。如果線程完成,然後確定。如果不是 - 我應該終止它的強制性。不建議

unsigned Counter = 0; 
void f() 
{ 
    HANDLE hThread; 
    unsigned threadID; 

    // Create the second thread. 
    hThread = (HANDLE)_beginthreadex(NULL, 0, DoSomething, NULL, 0, &threadID); 

    if (WAIT_TIMEOUT == WaitForSingleObject(hThread, 5000)) 
    { 
     TerminateThread(hThread, 1);  
     wcout << L"Process is Timed Out"; 
    } 
    else 
    { 
     wcout << L"Process is Ended OK"; 
    } 

    CloseHandle(hThread); 

    wcout << Counter; 
} 

unsigned int _stdcall DoSomething(void * /*dummy*/) 
{ 
    while (1) 
    { 

     ++Counter; 

    } 
    _endthreadex(0); 
    return 0; 
} 

問題

  1. TerminateThread()函數調用:

    簡化的例子在這裏。

  2. 正如我前面提到的,該線程在dll內運行。如果我終止線程使用TerminateThread()我的DLL不會卸載使用FreeLibrary()甚至FreeLibraryAndExitThread()。這兩個函數都會掛起。

如何終止線程並保持FreeLibrary() working?

謝謝。

+2

也許你應該看看在一個單獨的過程中主持胭脂DLL,並只是當事情變成梨形時殺死進程? – 2009-06-17 01:32:35

回答

11

不幸的是,您不能安全地任意終止線程。

TerminateThread會導致線程立即終止,即使線程正在鎖定或修改某些內部狀態。 TerminateThread可能會導致應用程序中的隨機掛起(如果線程持有鎖定)或崩潰(如果線程正在修改某個狀態並且保持不一致)

如果您不能相信DLL的行爲正確,導致您的重大可靠性問題,您應該將調用DLL的代碼移到單獨的進程中 - 終止進程會更安全。

+0

對突然終止線程的陷阱有很好的見解。 – nsantorello 2009-06-17 01:55:19