時間のかかる処理はワーカスレッドで、という話はよく聞くんですが、
ワーカスレッドのハンドルって、いつ閉じたらいいんでしょうか?
いくつか考えてみたんですが、どうもしっくりきません。
閉じずに放置、というのも考えたのですが、
アプリケーションの実行中に何度もスレッドを起動することを考えると
まずいかなと思います。
ワーカスレッドの中断ができて、かつ終了したら自動でハンドルを
閉じれるような方法があればベストなのですが。
定石のような方法がありましたら、ぜひ知りたいです。
1.待機関数でスレッドの終了を待つ
そもそも待ちたくないからワーカスレッドを使うわけで・・・
2.スレッドの終了時に閉じる
これはちゃんと閉じれてない気がします。
3.メインスレッドに終了を告げるプライベートメッセージをPost
確実そうですが、このためだけにプライベートメッセージを定義するのも
大げさな気もします。
スレッドに対して、ハンドルを必要とする操作(SuspendThread とか
GetExitCodeThread とか)を行わないのであれば、CreateThread で作成した直後に閉じ
てしまって構いません。
スレッドハンドルを閉じたからといって、スレッドが終了してしまうわけではありませ
んし、スレッドが終了しても、ハンドルは勝手には閉じられません。
> ワーカスレッドの中断ができて、
ということは、メインスレッドからワーカースレッドを SuspendThread できなければい
けないということですかね。じゃあ直後に閉じちゃダメだ。
仕様はどうなっているんですか?
ワーカースレッドは、同時に1つしか動かない? 同時に複数動きうる? とか。
ワーカースレッドを生成/中断/再開すべきタイミングは制御できる? できない?
とか。
どんなソフトを作ろうとしていて、ワーカースレッドで何をしようとしているのかがわ
かれば、より的確なアドバイスが出来そうな気がします。
ワーカースレッドだから終了待ち合わせが必要ないかと言うと
そういうわけではないと思いますよ。例えば、ワーカースレッドが
動作中に強制終了したいような場合は、外部からワーカースレッドに
中断して終わる指示を行い、終了を待つ必要があります。
ハンドルを閉じずに次から次とスレッドを起こすとハンドルリソースが
枯渇してスレッドが起こせなくなりますし。
あと、マルチスレッドで制御を行う場合、スレッドの制御をメインスレッドから
行う為の仕組みをきちんと考えておかないと目論見通りの動作の場合は良くても
目論見から外れた動作の時に困りますよ。
ワーカースレッドであってもこの辺の制御の仕組みは考えておくべきです。
なので待ち合わせしたくないからワーカースレッドと言う選択は間違いです。
UIが絡まないような長い処理だからワーカースレッドにすると言うのであれば、
わかりますけれど。
> 2.スレッドの終了時に閉じる
> これはちゃんと閉じれてない気がします。
MFC の実装をみてみると、スレッド側が CloaseHandle しています。
これでよいのでは。
少し返答が遅くなってしまいました。
ワーカスレッドの簡単な仕様ですが、
1.一度に一つしか起動しない。
以前のがまだ起動していたら、新規起動はしません。
ただし、何度も何度もスレッドを起動します。
だからちゃんと閉じたいです。
2.メインスレッドから中止可能
すいません、中断ではないのでSuspendはしない予定です。
ワーカスレッドをカプセル化したクラスへの参照を
メイン側で持って、フラグかイベントで終了指示を出します。
現状、メイン側は中止の指示だけ出して、終了したかどうかの
確認、待機は省略しています。
>CreateThread で作成した直後に閉じてしまって構いません。
え、いいんですか?
ハンドルを使う操作をしてないので、シャノンさんの
言うとおり先に閉じてしまっていいかもしれません。
>MFC の実装をみてみると、スレッド側が CloaseHandle しています。
まじですか。
今回はこれでもいいかも。
でも、メインからハンドルでスレッドの終了を待つ場合は
おかしくなりそうですね。ハンドルが勝手に閉じちゃったら。
> MFC の実装をみてみると、スレッド側が CloaseHandle しています。
> まじですか。
> 今回はこれでもいいかも。
> でも、メインからハンドルでスレッドの終了を待つ場合は
> おかしくなりそうですね。ハンドルが勝手に閉じちゃったら。
MFCの関数
「AfxBeginThread」を使った場合です。
ハンドルを使用する場合、
「CloaseHandle」しないという設定が出来るはずです。
スレッドのルーチン終了直前にフラグを立てて、メイン側終了時に
そのフラグをチェックすればいいのではないでしょうか。
マルチスレッドの場合そのフラグが増えるだけです。
ただマルチスレッドにおいて、「次から次へとスレッドを作成する。」
仕様の場合は検討しないといけないです。
>スレッドのルーチン終了直前にフラグを立てて、メイン側終了時に
>そのフラグをチェックすればいいのではないでしょうか。
そんな感じで、うまくいってます。
これで解決チェック付けときます。
#スレッドがたくさんなら、スレッドプールも選択肢ですかね。
済つけ忘れた・・・