解析C/C++でスレッドの運転を終了するにはどうすればいいですか?


スレッドの実行を終了するには、以下の方法があります。1、スレッド関数は戻ります。2、Exit Thread関数を呼び出すことで、スレッドは自動的にキャンセルされます。3、同じプロセスまたは他のプロセスのスレッドがTerminate Thread関数を呼び出します。4、ExitProcessとTerminate Process関数は、スレッドの実行を終了するためにも使用できます。
以下では、スレッドの運転を終了する方法を詳しく説明します。1-4は、スレッドが停止したときにどのような状況が発生するかを説明します。
1、スレッド関数の戻りは常にスレッドをこのような形に設計しなければならない。つまり、スレッドが実行を終了すると、それらは戻ることができる。これは全てのスレッドリソースが正確にクリアされることを保証する唯一の方法である。スレッドが戻ることができれば、(1)スレッド関数で作成したすべてのC++オブジェクトは、それらのキャンセル関数によって正しくキャンセルされます。2)オペレーティングシステムは、スレッドスタックが使用するメモリを正しく解放する(3)システムは、スレッドの終了コード(スレッドのカーネルオブジェクトでメンテナンス)をスレッド関数の戻り値として設定します。4)システムは、スレッドカーネルオブジェクトの使用を減少させます。
2、ExitThread関数は、強制的にスレッドを実行終了させるために、ExitThread関数をスレッドに呼び出すことができます。関数プロトタイプ:VOID ExitThread(DWORD dwExitCode)。この関数はスレッドの動作を終了し、スレッドが使用するオペレーティングシステムのリソースをすべて消去する結果となります。ただし、C++リソース(C++クラスオブジェクトなど)はキャンセルされません。このため、ExitThreadを呼び出して返すのではなく、スレッド関数から返したほうがいいです。もちろん、ExitThreadのdwExit Threadパラメータを使って、スレッドの終了コードをなぜ設定したのかをシステムに教えてもいいです。ExitThread関数は、スレッドが終了しているため、コードを実行できません。注意スレッド運転を終了するための最適な方法は、スレッド関数を元に戻すことです。しかし、このセクションで紹介した方法を使えば、ExitThread関数はWindowsが取り消しスレッドの関数として使用していることがわかるはずです。C/C++コードを作成するなら、ExitThreadを呼び出すべきではありません。Visual C++を使うべきです。運行期間ライブラリ関数_endthreadexMicrosoftのVisual C++コンパイラを使わないと、コンパイラのサプライヤーがExitThreadの代替機能を持っています。この代替関数は何であれ、使わなければなりません。
3、Terminate Thread関数はTerminate Thread関数を呼び出してもスレッドの運行を終了することができます。関数の原型:

BOOL TerminateThread(
HANDLE hThread,
DWORD dwExitCode);
  ExitThreadとは異なり、Exit Threadは常に呼び出しスレッドをキャンセルし、Terminate Threadは任意のスレッドをキャンセルすることができます。h Threadパラメータは、運転を終了したスレッドのハンドルを識別するために使用されます。スレッドが終了すると、その終了コードはdwExitCodeパラメータとして渡される値となります。同時に,スレッドのカーネルオブジェクトの使用カウントも減少した。Terminate Thread関数は非同期で実行される関数です。つまり、スレッドを終了したいとシステムに教えていますが、関数が戻ったら、スレッドが取り消されることは保証されません。スレッドが動作を終了したことを確実に知る必要がある場合は、WaitForSingleObjectまたは同様の関数を呼び出してスレッドのハンドルを渡す必要があります。よく設計されたアプリケーションはこの関数を使用しない。なぜなら、実行を終了したスレッドは元に戻す通知を受信できないからだ。スレッドは正しくクリアできず、自分がキャンセルされるのを防ぐことができません。なお、ExitThreadを返すか呼び出す方法でスレッドをキャンセルすると、スレッドのメモリスタックもキャンセルされます。しかし、Terminate Threadを使用すると、スレッドを持つプロセスが終了する前に、システムはスレッドのスタックをキャンセルしません。Microsoftはわざとこの方法でTerminate Threadを実現します。他のまだ実行されているスレッドが強制的にキャンセルされたスレッドスタックの値を参照すると、他のスレッドは不正アクセスの問題が発生します。キャンセルされたスレッドのスタックをメモリに残しておくと、他のスレッドがうまく動作します。また、スレッドが動作を終了すると、DLLは通常、通知を受信する。Terminate Threadを使用すれば、DLLは通知を受信しない。これは適切なクリアを阻止できる。
4、プロセス終了時にスレッドExitProcessとTerminate Process関数をキャンセルしても、スレッドの実行を終了するために使用できます。これらのスレッドは、実行を終了するプロセスのすべてのスレッドを実行終了させることになります。また、プロセス全体が閉じられているので、プロセスが使用するすべてのリソースはクリアされたに違いない。これはもちろん全スレッドのスタックを含む。この2つの関数は、残りのスレッドが強制的にキャンセルされ、残りのスレッドごとにTerminate Threadを呼び出すようになります。これは、正確なアプリケーションの消去が発生していないこと、すなわちC++オブジェクトのキャンセル関数が起動されていないこと、データがディスクに転送されていないことなどを意味する。
5、スレッドの運転終了時に発生する動作は、スレッドが停止した場合、以下のような動作が発生します。(1)スレッドが所有するすべてのユーザオブジェクトが解放されます。Windowsでは、これらのオブジェクトを作成するスレッドを含むプロセスによってほとんどのオブジェクトが所有されている。しかし、スレッドは2つのユーザオブジェクト、すなわちウィンドウとホックを持っている。スレッドが動作を終了すると、システムは任意のウィンドウを自動的にキャンセルし、スレッド作成またはインストールされたフックをアンマウントします。他のオブジェクトはスレッドを持つプロセスが実行終了した時にのみキャンセルされます(2)スレッドの終了コードはSTILL_ACTIVEは、Exit ThreadまたはTerminate Threadに渡すコードに変更しました。3)スレッド内核オブジェクトの状態が通知されました。4)スレッドがプロセスの最後のアクティビティスレッドである場合、システムはプロセスを終了したと見なしています。5)スレッドカーネルオブジェクトの使用カウントは1逓減した。スレッドが実行終了すると、それに関連するスレッドカーネルオブジェクトのすべての未終了の参照がオフになる前に、カーネルオブジェクトは自動的に解放されない。スレッドが動かなくなると、システムにはスレッドのハンドルを扱う他のスレッドがありません。しかし、他のスレッドは、hThreadによって識別されたスレッドが実行終了したかどうかを確認するために、GetExitcodeThreadを呼び出すことができる。動作が終了したら、その終了コードを決定します。関数プロトタイプ:

BOOL GetExitCodeThread(
HANDLE hThread,
PDWORD pdwExitCode);
終了コードの値はpdwExitCodeが指すDWORDに戻ります。GetExit CodeThreadを起動すると、スレッドがまだ実行されていない場合は、STILL_を使用します。ACTIVE識別子(0 x 103と定義)はDWORDに記入する。この関数が動作に成功すると、TRUEに戻ります。