2013-03-21 77 views
3

我有一個包含一個線程函數,其僞代碼看起來像一個執行DLL函數調用:Ç - 中斷其在線程

volatile BOOL stopped = FALSE; 

void StopEverything() 
{ 
    /* Enter critical section */ 
    stopped = TRUE; 
    /* Leave critical section */ 
} 

void workerThreadFunc() 
{ 
    Initialize(); 

    /* Checkpoint 1 */ 
    if(stopped) 
    { 
     /* Do cleanup */ 
     return; 
    } 

    doLaboriousTask1(); 

    /* Checkpoint 2 */ 
    if(stopped) 
    { 
     /* Do cleanup */ 
     return; 
    } 

    doLaboriousTask2(); 

    Uninitialize(); 
} 

而且在使用這個DLL的代碼,清理函數看起來像:

void cleanup() 
{ 
    StopEverything(); 

    /* Wait for all threads to exit */ 
    /* Do other cleanup */ 
} 

我的問題是雙重的:

  1. 有沒有更好的辦法從31e停止我的workerThreadFunc()執行而不是在各個檢查點進行這種檢查?
  2. 假設workerThreadFunc()卡在doLaboriousTask2()裏面,主應用程序調用StopEverything()。有沒有辦法中斷doLaboriousTask2()並立即退出?

謝謝!

+0

根據上下文的不同,一種選擇可能是將繁重的任務分解成單獨的進程,然後可以隨意終止。 – 2013-03-22 01:43:10

+0

@HarryJohnston,由於更昂貴的上下文切換,不會有單獨的進程顯着增加開銷? – 2013-03-22 04:59:06

+0

通常,進程上下文切換不會顯着增加開銷,特別是在具有多個CPU核心的系統上。但是你需要描述你的特定場景才能確定。 – 2013-03-22 07:42:59

回答

2

有沒有更好的方法來阻止我的workerThreadFunc()執行,而不是在各個檢查點進行這種檢查?

可能不是。沒有完全可靠的方式來先發制人地停止非託管代碼中的線程。任何聲稱要做的事情都會導致TerminateThread。文檔列出了使用該功能的各種可怕後果。例如:

  • 如果目標線程擁有臨界區,臨界區將不會被釋放。
  • 如果目標線程正在從堆中分配內存,堆鎖將不會被釋放。
  • 如果目標線程在終止時正在執行某些kernel32調用,則線程進程的kernel32狀態可能是 不一致。
  • 如果目標線程正在操縱共享DLL的全局狀態,則DLL的狀態可能會被破壞,從而影響到DLL的其他用戶。

你問:

有沒有辦法打斷doLaboriousTask2(),並立即退出?

那麼,你可以打電話TerminateThread,但由於文件中描述的所有原因,你幾乎肯定不應該那樣做。

+0

是的,我不想使用'TerminateThread'出於同樣的原因。我實際上遇到了[本文](http://www.codeproject.com/Articles/71529/Exception-Injection-Throwing-an-Exception-in-Other),它描述了在C++中這樣做的方法,但它看起來很親切可怕的,因爲它直接修改寄存器(或者只是我)。 – 2013-03-21 10:41:01

+0

我不認爲這比'TerminateThread'更好。 – 2013-03-21 10:48:14

+0

所以真的沒辦法?另外,您如何看待我的檢查點策略? – 2013-03-21 10:52:09