dllが死んだあとのスレッドの行方 – 固定ページ 2 – プログラミング – Home

dllが死んだあとのスレッドの行方
 
通知
すべてクリア

[解決済] dllが死んだあとのスレッドの行方

固定ページ 2 / 2

aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> 例外を発生させているのは、
> try
> {
> AAA aaa;
> throw e; // ←ココです。
> }
> catch(...)
> {
> FuncA();
> }

この場合、

> FuncAでAAAのデストラクタがコールされるはずですが、
> ちなみに、AAAのデストラクタでスレッド終了処理が入っています。

aaa のデストラクタは、throw の後、catch の前に呼ばれます。
FuncA が呼ばれる時点では、既にデストラクタは完了しています。

> SetWindowsHookEx + WH_MOUSE で他のアプリケーションのアドレス空間にロードした
> DLLは、その内部で例えばアクセス違反を起こすと、ロード先のアプリケーションは
> 無事なまま、アンロードされます。

そうなんですか。知りませんでした。ありがとうございます。


返信引用
n
 n
(@n)
ゲスト
結合: 21年前
投稿: 90
 

> ロード先のアプリケーションは無事なまま、アンロードされます。

これはXPの場合でした。
Meでやったらロード先のアプリケーションごと死んでエライことになりました(汗


返信引用
・・・
 ・・・
(@・・・)
ゲスト
結合: 22年前
投稿: 16
 

再度、回答ではなくて、感想になるかも知れませんが・・・。

1.roccyさんが意図したとおりにプログラムが動かないのであれば
原因が「dll」にあるのか、それとも「スレッド」にあるのか
はたまた、両方の併用にあるのか、切り分けて欲しいと思いました。
つまり、「dll」を使わず直接「スレッド」を生成したときは
どうなるのか、結果が欲しいと思いました。
前回の感想「5.」でも思いはにじませましたが、明記した方が
良かったのでしょうね。

2.確認ですが、「dll」において「MFC」のようなクラスを作成し
「スレッド」の処理をするということですね?

>デストラクタでスレッドが終了するのを待っているが、
[1]待つことが、仕様としてもプログラムとしても不都合がなければ、
それでも可と思います。通常は↓になるのでしょうか(終了の検出)
http://kkkon.hp.infoseek.co.jp/tips/VC/beginthread.shtml

[2]あと、GetExitCodeThread なんていうのはどうでしょうか。
スレッドが終了していないのであれば、是非もなく.TerminateThread
スレッドでCランタイムを使わないのであれば、
CreateThread(・・・CREATE_SUSPENDED、)
ResumeThread
ExitThread
を使うことになると思いますが・・・。

>「ある状態」から復旧したとき、そのあとの処理が
>正しく行われるのでしょうか?
「ある状態」・・・?、これも、難しい質問ですね。
だいたい、具体的なソースを提示してくれていません。
#具体的なソースがれば、必ず解決する訳ではありませんし、
#守秘義務のようなものもあるかも知れませんが・・・。

3.要望としては、roccyさんの趣味の範囲であれば、不具合の
原因が特定できなくても良いと思いますが、仕事であれば
是非、原因を突き止めて欲しく思います。


返信引用
roccy
 roccy
(@roccy)
ゲスト
結合: 23年前
投稿: 82
Topic starter  

・・・さん、ありがとうございます。

>1.roccyさんが意図したとおりにプログラムが動かないのであれば
>原因が「dll」にあるのか、それとも「スレッド」にあるのか
>はたまた、両方の併用にあるのか、切り分けて欲しいと思いました。
>つまり、「dll」を使わず直接「スレッド」を生成したときは
>どうなるのか、結果が欲しいと思いました。
>前回の感想「5.」でも思いはにじませましたが、明記した方が
>良かったのでしょうね。
スレッドが終了していなかったのが原因です。
「dll」を使っても、使わなくても同様の結果になります。

>2.確認ですが、「dll」において「MFC」のようなクラスを作成し
>「スレッド」の処理をするということですね?
そのとおりです。

>>「ある状態」から復旧したとき、そのあとの処理が
>>正しく行われるのでしょうか?
>「ある状態」・・・?、これも、難しい質問ですね。
>だいたい、具体的なソースを提示してくれていません。
>#具体的なソースがれば、必ず解決する訳ではありませんし、
>#守秘義務のようなものもあるかも知れませんが・・・。
曖昧な言い方をしてしまったことが問題を拡大してしまったようです。
「ある状態」とは、ダイアログを表示してオペレータの入力を待っている状態です。
ダイアログを表示するとスレッドが停止する仕様になっているのです。
普通は、ダイアログを表示したあと、「はい」「いいえ」を
すぐに押すのですが、押さずにずっと待っていると
スレッドが終了する前に、メインのスレッドが終了してしまう状況に
陥ってしまっていたのです。

>3.要望としては、roccyさんの趣味の範囲であれば、不具合の
>原因が特定できなくても良いと思いますが、仕事であれば
>是非、原因を突き止めて欲しく思います。
原因は、スレッドが終了していないことが原因です。
スレッドが終了していないのは、「ある状態」になっていることが
原因です。

#まだ、いくつか疑問点がありますが、前述のとおりの
対処で解決いたしました。すべて、皆さんの貴重なご意見の
お陰です。

>対処方法としては、
>1.スレッド終了時には、終了通知を送る。
>2.スレッドが終了していない場合(「ある状態」の場合)は、
> スレッドが終了するのを待つ。
>ここで気になるのが、
>・デストラクタでスレッドが終了するのを待っているが、
> 「ある状態」は、長い時間そのままであることもある。
> そのため、INFINITEで永久に待つことになるが、
> デストラクタで処理が止まった状態になってしまうが、
> 「ある状態」から復旧したとき、そのあとの処理が
> 正しく行われるのでしょうか?
>・例外を発生させた場合、デストラクタが呼ばれない
> ようですが、本当にそうなのですか?ブレークを張ってても
> ブレークで止まりませんでした。

ありがとうございました。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> 「ある状態」とは、ダイアログを表示してオペレータの入力を待っている状態です。
> ダイアログを表示するとスレッドが停止する仕様になっているのです。
> 普通は、ダイアログを表示したあと、「はい」「いいえ」を
> すぐに押すのですが、押さずにずっと待っていると
> スレッドが終了する前に、メインのスレッドが終了してしまう状況に
> 陥ってしまっていたのです。

サブスレッドでモーダルダイアログを表示しているけれど、スレッドが違うので、メイン
スレッドから見るとモードレスダイアログになってしまっている状況かしら?


返信引用
・・・
 ・・・
(@・・・)
ゲスト
結合: 22年前
投稿: 16
 

>シャノンさんへ

他の掲示板からの抜粋ですが・・・(過去ログになっているので)
ご存知とは思いますが、念のためモーダルダイアログの仕様です。
>junさんの報告から
ダイアログ開始時に「オーナーウィンドウを無効にする」
(MSDNでWin32APIのDialogBoxマクロ参照)
>ジェットさんの報告から
DialogBox マクロでダイアログを作成すると、オーナーウィンドウは
確実に無効化されます(WM_ENABLE メッセージが来ます)。
また、内部で独自のループ処理をしているので、ダイアログを閉じるまで
制御が戻りません。

この原則はスレッドが違っても変わらないようです。
ただし、今回のケースで確かめた訳ではないです。
MFCのGUIスレッドで、独立したウィンドウの動きを
期待して、モーダルダイアログを作ったときの場合ですが。

#質問した方が、それなりに目処がついたのは喜ぶべきことと
#考えますが、回答する方として多少の不完全燃焼は残りますね。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> この原則はスレッドが違っても変わらないようです。

そうですか。
スレッドが違ってもモーダルはモーダルなのですね。
ご指摘ありがとうございます。

roccy さんの

> 「ある状態」とは、ダイアログを表示してオペレータの入力を待っている状態です。
> ダイアログを表示するとスレッドが停止する仕様になっているのです。
> 普通は、ダイアログを表示したあと、「はい」「いいえ」を
> すぐに押すのですが、押さずにずっと待っていると
> スレッドが終了する前に、メインのスレッドが終了してしまう状況に
> 陥ってしまっていたのです。

この書き込みから、「ダイアログが開いているのにメインウィンドウが閉じられてしまっ
た」というケースを想定しての書き込みでした。
が、そうでないとすると…

> スレッドが終了する前に、メインのスレッドが終了してしまう状況に
> 陥ってしまっていたのです。

これがバグでなく仕様に起因するものならば、なんだかおかしい気がします。

> 「ある状態」とは、ダイアログを表示してオペレータの入力を待っている状態です。

通常、このような場合、オペレータが入力した値を受けて後続の処理を行うため、
メインスレッドの方では精々、バックグラウンド処理くらいしかできないのが定石である
と思います。
それを、オペレータが入力しなくてもメインスレッドが終了できるということは、メイン
スレッドとサブスレッドに何ら関係が無いということに…?
そもそも、マルチスレッドにする必要があったのかどうか、見直すべきではあるまいか?
 と思うのですが、勘繰り過ぎでしょうか。


返信引用
・・・
 ・・・
(@・・・)
ゲスト
結合: 22年前
投稿: 16
 

>シャノンさんへ

>これがバグでなく仕様に起因するものならば、なんだかおかしい気がします。
多分、「dllが死んだあとのスレッドの行方」の掲示板スレ主も
この辺りの仕様で、難題にぶつかったような気がします。
それで、示された対処方法で対応しようとしているのではと思います。
#あくまでも、推測の域をでませんが・・・・

仕様については、モーダルともモードレスとも明言していません。

選択肢として、モードレスが候補にあがる場合もあるようです。
#著作権で訴えられないかと、多少の不安を覚えつつ・・・。
やはり、↓は他の掲示板からの抜粋ですが。(名前は変更)

○ ×2003/12/×× 
「○ ×」と申します。

MessageBox()を表示すると、
ここで処理が中断しますが、
表示しまたまま処理が次のステップへ
進むようなオプションはないでしょうか?

↑の質問に対しての解決策として、
次の3つの方法が提案されています
1.マルチスレッド
2.モードレスダイアログ
3.新しいプロセスを生成して、そこで表示

それで、話を今回のケースに戻しますが
1.モードレスの場合も考えられますし、
2.背景のオーナーウィンドウが無効のまま、
プライマリースレッドの方が、サブスレッドにお構いなく、
処理を進めた結果とも考えられます。

2.も考えられるの理由については、プライマリースレッドの方は
ユーザーインターフェースからのイベントを受付られないだけで、
他の処理はできると思うので。(実際には確かめていません)

#私としては、第三のGUIスレッドも考えられるのでは考えます。

話にまとまりがなく申し訳ないです。

#この掲示板の質問者は解決しているので、続きは他の適切な
#ところを案内して頂ければ、浅学な知識が役に立つかも
#知れませんが・・・。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> 2.も考えられるの理由については、プライマリースレッドの方は
> ユーザーインターフェースからのイベントを受付られないだけで、
> 他の処理はできると思うので。(実際には確かめていません)

確かに可能性としてありえなくはないですが、それはつまり、ユーザの入力に時間制限が
つくということなので、ゲームでもない限りは、「普通はそんな不親切な(スレ主さんゴ
メンナサイ)インターフェイスは作らないだろう」との予想のもと、先のような書き込み
をした次第です。

が、真相がどうであれ、既に解決したスレをこれ以上伸ばすのも申し訳ありませんので、
これにて一旦閉幕とさせていただきたく存じます。


返信引用
roccy
 roccy
(@roccy)
ゲスト
結合: 23年前
投稿: 82
Topic starter  

みなさん、多くのご意見ありがとうございます。

スレッドとダイアログ表示の詳細については、あまりお答えできませんが、
1.ダイアログを表示させるメインスレッド
2.内部処理をするスレッド
3.メインスレッドに対して処理するスレッド
大きく3つに分かれます。
2のスレッドは、1のスレッドから起動されます。
3のスレッドは、2のスレッドから起動されます。
あるボタンを押すと、1のスレッドがダイアログを表示します。
2のスレッドは、ダイアログが表示されると停止します。
同様に3のスレッドもダイアログが表示されると停止します。
そして、2のスレッドが3のスレッドを終了させようとした
瞬間にボタンを押すと、3のスレッドが停止したまま、
終了させようとしてしまいます。
こういった作りが問題であるのかもしれませんが、
ひとまず、皆さまのおかげで解決いたしました。

ありがとうございました。


返信引用
固定ページ 2 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました