関数を使用してWindowsでスレッドを終了した場合TerminateThread
、そのスレッドは関数が戻ったときに実際に終了しますか、それとも終了は無意味ですか?
3 に答える
「実際に終了した」を定義します。ドキュメントには、スレッドはこれ以上ユーザーモードコードを実行できないと記載されているため、効果的に:はい、終了します。そのスレッドによってコードが実行されることはありません。
終了直後に「WaitForSingleObject」を実行した場合、Windowsが実行しているクリーンアップのために、まだ若干の遅延が発生する可能性があると思います。
ちなみに、TerminateThreadは、スレッドを終了するための最悪の方法です。スレッドに停止を指示するグローバル変数やイベントなど、他の同期手段を使用してみてください。
スレッドを終了することは、スレッドごとのレベルでのみ、プロセスを強制終了することに似ています。実際には、ターゲットスレッドで(キャッチできない)シグナルを発生させることで実装できます。
結果は基本的に同じです。プログラムは特定の予測可能な状態ではありません。デッドスレッドでできることはあまりありません。プログラムの制御フローは一般的に不確定になるため、スレッドが終了した場合のプログラムの動作について推論することは非常に困難です。
基本的に、スレッドが非常に狭く、具体的で制限された処理を行っていない限り(たとえば、1秒に1回アトミックカウンターをインクリメントする)、スレッドを終了する必要性や、スレッド終了後のプログラムの状態について適切なモデルはありません。
しないでください。スレッドと通信できるように、またエントリ関数が戻ることができるように、スレッドを設計してください。最終的には常にすべてのスレッドに参加し、すべてを説明できるようにプログラムを設計します。
同期呼び出しです。これは、必ずしもすぐに戻ることを意味するわけではありません。OSがコア間ドライバーを使用してスレッドを停止する必要がある場合(つまり、実際には終了を要求するスレッドとは異なるコアで実行されている場合)、何らかのブロッキングが発生する可能性があります。 )。
他の人によって明確に投稿されているように、アプリの実行中にユーザーコードからTerminateThreadを呼び出すことには問題があります(アプリ/プロセスの終了時にそれを使用するカーネルとは異なります)。
私は、TerminateThreadを使用して、またはその他の方法で、アプリの実行中にスレッドをまったく終了しないように非常に努力しています。アプリの存続期間中のスレッドとスレッドプールは、多くの場合、OSがアプリの終了時にそれらを破棄する前に明示的な終了を必要としません。