Thread.Abort メソッドを利用してスレッドを終了させる際の注意点について

こんにちは、Platform SDK (Windows SDK) サポートチームです。
今回は、System.Threading 名前空間の Thread.Abort メソッド (以降、Abort メソッド) を利用してスレッドを終了させた場合に発生する可能性がある現象についてご案内いたします。

 

現象

Abort メソッドはスレッドを強制終了させるメソッドです。

Thread.Abort メソッド
< https://msdn.microsoft.com/ja-jp/library/system.threading.thread.abort.aspx >

Abort メソッドを利用してスレッドを強制終了させると、以下の様な現象が発生する可能性があります。

・ オブジェクト ハンドルやメモリ等のリーク
・ プロセスの強制終了
・ プロセスのデッドロック

 

原因

スレッドが開始すると、そのスレッド内部で必要な様々なリソースの確保や初期化処理が行われます。
そしてスレッドが終了するタイミングでは、そのスレッド内部で確保・初期化された様々なリソースの解放処理が行われます。
ところが Abort メソッドを利用してスレッドを強制終了した場合は、これらのリソースの解放処理が必ず行われる保証がありません。
そして、これらのリソースの解放処理が行われなかった結果として、前述したような現象に発展する可能性があります。

 

回避策

可能な限り、Abort メソッドを利用してスレッドを強制終了しないようにします。
たとえば、以下のように自分自身を自発的に終了させる仕組みをスレッド (下記例ではスレッド B) 内に実装しておくことで、その仕組みを利用した外部スレッド (下記例ではスレッド A) が、安全にそのスレッド (下記例ではスレッド B) を終了させることができるようになります。

- スレッド A からスレッド B を終了させたい場合の例
1. スレッド A とスレッド B が参照できるフラグ変数を用意します。
2. スレッド B は、初期化処理を実行したあと、定期的にこのフラグ変数を参照しながら目的の処理を遂行します。
3. フラグ変数が ON であれば、必要な終了処理を行った後、自分自身をスレッド終了します。
4. スレッド A は、スレッド B を終了させたいタイミングで、フラグ変数を ON にします。

 

参考情報

Win32 API の TerminateThread 関数も、Abort メソッドと同様にスレッドを強制終了させる方法です。
このため、Abort メソッドと同様の現象を引き起こす可能性があります。

TerminateThread
<https://msdn.microsoft.com/ja-jp/library/cc429380.aspx>
TerminateThread 関数は、スレッドを無条件に終了させる危険な関数であり、非常に特別な場合にのみ使うべきです。