Win2000,VC++6.0,MFC です。
AfxBeginThreadを使ってマルチスレッドプログラム(DLL)を作成しています。
外部exeからDLLを呼び出し、そのなかでAfxBeginThreadを呼んでスレッドを作成
していますが、exeによってAfxBeginThread処理が返ってこないことがあります。
下のように書いてます。
(DLLのコード)
UINT ThreadProc(LPVOID)
{
・・・
AfxEndThread(0,TRUE);
}
__declspec(dllexport) int subproc()
{
・・・
sub_init();
・・・
}
void sub_init()
{
AfxBeginThread( ThreadProc, (LPVOID)NULL ); <-ここで止まる
・・・
}
exeによって止まるもの正常に動くものがあるのですが、AfxBeginThreadが止まる原因は何が
あるのでしょうか。
大事なものを書き忘れてるとみた
サンプルとか見てみるとすぐわかる
皆さんこんばんは。すごい久々の書き込みでっす。うーん、というかこういう[危]なプ
ログラムよりも、もっと普通にCWinThreadから派生クラス作ってそのクラスでスレッド
実行させる方が良いと思うっス。
なかなか皆さん意地悪なようで。
結局原因がわからないままCWinThreadから派生クラス作って解決とは。
それに普通って何だよ。派生クラスじゃない方法は普通じゃないって言うのかよ。
> 結局原因がわからないままCWinThreadから派生クラス作って解決とは。
今このプログラムをその場しのぎで動くようにしてもまた次にすぐ詰まるでしょ?(ス
レッド同期とか色々)。それより基本に忠実にプログラムした方が後々楽だって事です
よ。
> それに普通って何だよ。派生クラスじゃない方法は普通じゃないって言うのかよ。
MFCプログラミングの基本はMFCクラスから派生してく方法でしょ!派生クラスじゃない
方法は普通じゃなく上級でしょ。
> なかなか皆さん意地悪なようで。
質問にまったく答えず、他者のレスにケチつけてるだけのあんたの方がよほど性質悪い
ですな。
>MFCプログラミングの基本はMFCクラスから派生してく方法でしょ!派生クラスじゃない
>方法は普通じゃなく上級でしょ。
根拠がよく分かりませんが、
ワーカースレッドに関しては、CWinThreadから派生しないほうが簡単で普通でしょう。
本題ですが、AfxBeginThreadで止まっていることをどう確認したのでしょうか?
> exeによって止まるもの正常に動くものがあるのですが
どのような exe がとまるのかとかの情報もほしいかも。
(非MFCの exe から subproc を呼んでいるとか?)
とりあえず、スレッドの中でAfxEndThreadを呼んじゃいけないと思う。
あ、そうでもないのか??
AfxEndThreadの説明に、
>終了するスレッドの内部からは呼び出さないでください。
って書いてあるのはなんなんだ?
AfxEndThread に関して言えば「当該スレッドの中で呼べ」とありますね。
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/vcmfc98/html/_mfc_afxendthread.asp
ローカルオブジェクトのデストラクタを呼ばずにスレッドだけ終了してしまうから、
私なら絶対に使いませんけど AfxEndThread
動かない EXE ってシングルスレッドモデルでコンパイルされていませんか?
> ワーカースレッドに関しては、CWinThreadから派生しないほうが簡単で普通でしょ
う。
★afxで始まる命令って古いプログラムとの互換性のタメに残ってると認識してたんです
けど?普通じゃなくて古いの間違いなのでは?簡単という事に関しても今後プログラム
が大きくなればスレッドをクラスにしておいた方が楽ですよ。えっ?AfxBeginThreadと
CWinThreadのどちらが正統派か?という議論のスレではないって?失礼!
横道失礼
>★afxで始まる命令って古いプログラムとの互換性のタメに残ってると認識してたんです
>けど?
単にグローバルだというだけみたいですよ。
http://msdn2.microsoft.com/ja-jp/library/f2dch7fb(VS.80).aspx
の最後のメモを参照してください。
それに、AfxBeginThreadの戻り値は、CWinThread*です。
派生はしていませんが、CWinThreadを使っていますよ。
> 派生はしていませんが、CWinThreadを使っていますよ。
情報どうも。しかし、だったらなおさら、なぜCWinThreadの作成をAfxBeginThreadに一
任させてムキ身の関数に処理投げる方法が「普通で簡単」なのか理解できません。正し
いスレッドの終了方法すら意見合わないみたいですし、、、。だったら派生クラス作っ
てから、CWinThread::CreateThread()でスタートさせて、派生クラス内でスレッド走ら
せる方法の方が良いと思うっス。CThread::CThread()、CThread::InitInstance()、
CThread::ExitInstance()、etc、、、とかOWして使えば便利で安全ですよ。てかMFCてそ
ういう使い方が普通でしょ(T-T)。(それとも私は変なプログラマー?)。
バラモンさん、脱線しちゃってすんません。
AfxEndThreadは、CWinThreadを派生しようがしまいが、
使えますので、比較の対象にはなりません。
InitInstanceや、ExitInstanceはワーカースレッドでは使えません。
それどころか、メンバ変数を暗黙に使えるということもありません。
さらには、処理関数をCWinThreadに設定する方法もドキュメント化されていません。
(これは見落としの可能性もありますが)
もしかして、ともさんは、ワーカースレッドのつもりで、
ユーザー インターフェイス スレッドを作成されているのではないですか?
MSDN の「マルチスレッド : ワーカー スレッドの生成」で紹介されてる手段は、
MFC の普通で、標準的な用法だと思います。
http://www.microsoft.com/japan/developer/library/vccore/_core_multithreading.
3a_.creating_worker_threads.htm
<MSDN>
ワーカー スレッドの作成は比較的簡単な作業です。
スレッドを実行するために必要な手順は、
(1) 制御関数の作成、
(2) スレッドの起動の 2 つだけです。
CWinThread の専用の派生クラスが必要ないのであれば、クラスを派生する必要はありません。
通常、単純なワーカー スレッドを実行する場合は、CWinThread がそのまま使えます。
-- snip --
スレッドの起動
関数 AfxBeginThread にはオーバーロード バージョンが 2 つあります。
1 つは、それぞれユーザー インターフェイス スレッド用で、
もう 1 つはワーカー スレッド用です。
ワーカー スレッドを起動するには、AfxBeginThread を呼び出して、以下の情報を渡します。
-- snip --
</MSDN>