VC++6.0(SP2)、WinXp
スレッドの基本について教えてください。
現在、起動時にAfxBeginThreadでワーカスレッドを作成し、アプリ終了まで動かしてい
ます。
正常に動いていれば、アプリとスレッドはほぼ同時に終了するはずですが、アプリが暴
走したなどの理由により、スレッドだけが取り残されてしまう可能性はあるのでしょう
か?
もし、そうなる可能性があるのであれば、生成元が居なくなったら自殺するような仕組
みを入れたいのですが、生成元が存在しているか否かを判断はどうしたらよいのでしょ
うか?
また、アプリ終了時、スレッドの終了を待つようにしていますが、一定時間経過しても
終了しない場合、TerminateThreadを使って強制終了させるようにしました。
テスト的に、スレッドが終了しない状態を作り、強制終了させるとデバッガにメモリリ
ークしたと表示されます。
強制終了なのでメモリリークする(行儀が悪い)のは仕方がないのでしょうか?
ご存知のかたいらっしゃいましたら、アドバイスお願いいたします。
そもそもの話として「アプリの終了」というのが何か?はOK?
・アプリケーションに属するすべてのスレッドが終了する=アプリの終了
・OSがアプリ起動時に作った最初のスレッドが終了する=アプリの終了
・それ以外の何か
どれのことだかわかっているかな?
> 強制終了なのでメモリリークする(行儀が悪い)のは仕方がないのでしょうか?
ある意味 Yes ある意味 No
純粋に「メモリ」だけの話なら、行儀が悪いだけで済むだろう。
ファイルに対して書き込むべきデータを書く前に強制終了させられているのなら、
不完全なファイルができてしまうことになりバグといってもいいかもしれない。
# タスクマネージャでアプリを強制的に終了させたのではなくて
# ごくまっとうな操作としてアプリを終了する場合にスレッド強制終了させなきゃならん
# としたら、明らかにバグ。
>もし、そうなる可能性があるのであれば、
そうならないように作りましょう
>生成元が居なくなったら自殺するような仕組
「正常終了できなかったスレッド」は「正常に動作してないスレッド」なので
そんな仕組みを入れたとしても、その仕組みが正常に動く可能性がないが?
>強制終了なのでメモリリークする(行儀が悪い)のは仕方がないのでしょうか?
仕方がない。
「正常に終了できなかった」からの
「強制終了」なのであって
それが「正常でない終了」になるのは当たり前
進むべきは「スレッドが正常に終了する」ようにつくるのであって
「正常に終了しなかったときに、できる限りお行儀よく
なんとしても正常終了っぽくさせる」ではないはず
> 強制終了なのでメモリリークする(行儀が悪い)のは仕方がないのでしょうか?
http://msdn.microsoft.com/ja-jp/library/cc429380.aspx
↑ワーストケースの説明を読めば分かりますが、既出のようにメモリ以外の問題で
行儀が悪いではすまないこともありえる「最後の手段」ですから、
そうなってしまった以上そこは仕方ないのでは。
そもそも、そんな自体に陥らないようにするべきで、悩むならそちらかと。
tetrapodさん、レスありがとうございます。
>そもそもの話として「アプリの終了」というのが何か?はOK?
・アプリケーションに属するすべてのスレッドが終了する=アプリの終了
と理解しています。
># タスクマネージャでアプリを強制的に終了させたのではなくて
># ごくまっとうな操作としてアプリを終了する場合にスレッド強制終了させなきゃな
らん
># としたら、明らかにバグ。
もちろん、まっとうな操作で終了を待っていますが、万が一終了しなかった場合に強制
終了を組み込もうとした次第です。
ryoさん、レスありがとうございます。
>「正常終了できなかったスレッド」は「正常に動作してないスレッド」なので
>そんな仕組みを入れたとしても、その仕組みが正常に動く可能性がないが?
そうですよね。確かに。
Banさん、レスありがとうございます。
> http://msdn.microsoft.com/ja-jp/library/cc429380.aspx
>↑ワーストケースの説明を読めば分かりますが、既出のようにメモリ以外の問題で
>行儀が悪いではすまないこともありえる「最後の手段」ですから、
>そうなってしまった以上そこは仕方ないのでは。
そうですよね、強制終了ですからね。
http://msdn.microsoft.com/ja-jp/library/cc429099.aspx
によるとアプリの終了とは ExitProcess 関数を呼び出すことであるわけだ。
だから任意のスレッドから明示的に ExitProcess を呼び出せばアプリ終了。
ただし、アプリ起動時にOSが生成したスレッドが終了するとき
(要するに WinMain や main が終了して Runtime Library に処理を戻すとき)
には Runtime Library 中から ExitProcess が呼ばれるので、
> ・OSがアプリ起動時に作った最初のスレッドが終了する=アプリの終了
でもある。
さて先の MSDN 解説ページ中には以下の記述がある。
> 2.プロセス内のすべてのスレッドが動作を終了します。
この日本語解説の文言が微妙なので英語解説を見ると
http://msdn.microsoft.com/en-us/library/ms885217.aspx
> All threads in the process terminate their execution.
terminate の訳としては「終了する」という能動態ではなく、むしろ
「終了させられる」「打ち切られる」「抹消される」という受動態であるべきかな・・・
なので
「アプリケーション終了」の際にはすべてのスレッドが抹消させられる
ということ。
抹消させられる=正しい終了処理など一切無しに、ただ実行されなくなる。
> アプリが暴走したなどの理由により、
暴走している=まだ終了していないだと思うが・・・
> スレッドだけが取り残されてしまう可能性はあるのでしょうか?
終了しているのであれば杞憂。