スレッドの注意点

VC++でスレッドを扱う方法は3つの方法があるようです。
  1. CreateThread, ExitThread APIの利用
  2. _beginthread, _endthread 関数の利用
  3. AfxBeginThread, AfxEndThread 関数の利用

CreateThread, ExitThread APIの利用

CreateThread APIを利用する場合は、スレッドの制御関数内で、Cランタイム関数とMFCを利用しないことが条件になるようです。
CreateThread APIで生成されたスレッドでは、Cランタイム関数が使えない為のようです。
CreateThread APIで作成したスレッドを内部で停止する場合は、ExitThread APIを呼び出すか、returnで制御関数から抜け出す必要があります。

また、MFCを利用してしまうと、スレッド終了時にメモリリークが発生するようです。
仕事でCreateThread内でMFCを利用するスレッドを扱ったとき、1000回以上スレッドを作り直したらスレッドが作成できなくなるトラブルに遭遇しました。

_beginthread, _endthread 関数の利用

_beginthread 関数はスレッド内でCランタイムを扱う場合に利用するようです。_beginthread 関数自体がCの関数なので当然と言えば当然ですが・・
_beginthread 関数で作成したスレッドを内部で停止する場合は、_endthread 関数を呼び出すか、returnで制御関数から抜け出す必要があります。

AfxBeginThread, AfxEndThread 関数の利用

AfxBeginThread 関数はMFCを利用する場合に使用します。
AfxBeginThread 関数で作成するスレッドには2種類のスレッドが存在します。

先にも書きましたが、MFCを扱うスレッドでCreateThread APIを利用するとトラブルの元になるので、必ず、AfxBeginThread 関数を利用する必要があります。

AfxBeginThread 関数で作成したスレッドを内部で停止する場合は、AfxEndThread 関数を呼び出すか、returnで制御関数から抜け出す必要があります。
AfxBeginThread 関数で作成したスレッドはTerminateThread API でスレッド停止してはいけません。

TerminateThread API でスレッドを強制終了させた場合、後始末の処理が行なわれなくなる為、メモリリークの原因になります。
AfxBeginThread 関数で作成したスレッドを終了させたい場合は、CWinThread クラスのPostThreadMessage 関数でWM_QUITを送信するか、停止用フラグを定期的に チェックし、停止用フラグがonになった場合にAfxEndThread 関数でスレッドを終了させるような仕組みにする必要があります。

ワーカースレッドの場合でCWinThreadのm_bAoutDeleteをFALSEにした場合は、delete 演算子で明示的にCWinThread のポインタを削除する必要があります。
(AfxBeginThread 関数のソースを見ると、DEBUG_NEWでCWinThreadのポインタを生成しているので問題ないはず。)
ユーザーインターフェイススレッドは不明。

参考情報

  • [00005440](SET)] MFCで_beginthreadを使ってはいけない理由
  • MFC Tips