2012-06-27 28 views
6

"CreateThread"関数でスレッドを作成しました。CloseHandleでWindows C++スレッドを閉じる

このスレッドでは、(入力を読み取る) 'while(true)'ループがあります。

今のところ、スレッドを閉じるには、「CloseHandle」関数を使用します。

これは正しいことですか?または、私は 'while(true)'ループを終了し、 'CloseHandle'関数を使用する必要がありますか?

おかげ

答えて

8

CloseHandle()はスレッドを破棄、終了、またはsupspendせず、ハンドル自体を破棄するだけです(スレッドを強制終了または待機させるハンドルはありません)。スレッドは正常に動作し続けます(私はこれを多くの場合使用しています)、それを停止する唯一の方法はスレッド関数(ThreadProc())を終了するか、それを終了させることです。

6

スレッドがいくつかのリソース(すなわち、ファイルディスクリプタ)を割り振ることができるので、一般的には、この(のTerminateThreadを呼び出す)は、全体のプロセスが終了するまで使用できなくなる行うには悪いことです。さらに、CloseHandleはスレッドを停止しません。

あなたがスレッド内でいくつかの長い操作を持っている場合は、少なくとも

while(!ShouldExit) 
{ 
    DoOneMoreIteration(); 
} 

サイクルを使用します。このようにして、ShouldExitを1(またはC++とbool変数の場合は 'true')に設定し、このスレッドのハンドル上でWaitForSingleObject呼び出しを終了してスレッドを終了させることができます。

eranのコメントの場合:ShouldExitは 'volatile'と宣言する必要があります。

入力を待っているのであれば、ノンブロッキング(「オーバーラップ」)I/Oを標準入力と併用することができます。

例えば、この質問を参照してください。(CPUのオーバーバーンを避ける)物事をより良くするために

HANDLE h = GetStdHandle(STD_INPUT_HANDLE); 

while(!ShouldExit) { 
    if(WaitForSingleObject(h, FALSE, SomeTimeoutValue) == WAIT_OBJECT_0) 
    { 
     ... use std::cin - it has some input and won't block 
    } 
} 

ようなものになるだろうChecking Win32 file streams for available input

はたWaitForMultipleObjectsを使用して、いくつかの外部イベントにループの外で破ります。

/// Global var 
HANDLE SomeGlobalEvent; 

/// ThreadProc(): 
HANDLE h[2]; 
h[0] = GetStdHandle(STD_INPUT_HANDLE); 
h[1] = SomeGlobalEvent; 

while(true) { 
    DWORD which = WaitForMultipleObjects(2, h, FALSE, SomeTimeoutValue); 
    if(which == WAIT_OBJECT_0) 
    { 
     ... use std::cin - it has some input and won't block 
    } else 
    if(which == WAIT_OBJECT_1) 
    { 
     // got the termination event 
     break; 
    } 
} 


/// "Main" thread: 

SomeGlobalEvent = CreateEvent(NULL, false, false, NULL); 

HANDLE hThread = _beginthread(ThreadProc, 4096, NULL); 

.... 
/// send termination signal 
SetEvent(SomeGlobalEvent); 

/// Wait for thread completion 
WaitForSingleObject(hThread); 
+3

@kakush、もしあなたが 'ShouldExit'に行くなら、' volatile'と宣言してください。さもなければ、それはトリックをしないかもしれない。 – eran

+0

@eran、そうです。 –

+1

@eran: 'volatile 'トリックは、Visual C++コンパイラでは*のみ*動作します。他のコンパイラでは動作しないかもしれません。 –

3

最高のことは、ドキュメントを慎重に読むことです。 Win32 APIは十分に文書化されています。 MSDN on CreateThread in the Remarks sectionから

はそれが

スレッドの実行がlpStartAddr パラメータで指定された関数から始まると言います。この関数が返された場合、ExitThread関数の暗黙的な呼び出しでスレッドを終了させるには、DWORD戻り値を使用して を終了します。 GetExitCodeThread関数を使用して、スレッドの戻り値を取得します。

これ以降は、スレッドエントリ機能にそのジョブを実行させて終了させる必要があります。私。スレッドエントリ関数を返すループを終了します。

関連する問題