• ベストアンサー

スレッド終了を待つ間に開放されたデータを参照

MFCのアプリケーションで、 マルチスレッド処理中にユーザがアプリを終了できる場面があります。 スレッドの末尾にフラグを置き、 それがOFFなら抜ける、というコードを書いているのですが、 そこにたどり着くまでに、開放されたデータ等を参照してエラーが発生します。 CMainFrame::OnDestroy() の先頭でフラグをOFFにし、 ::WaitForSingleObject(pThread, INFINITE); を書いたのですが、素通りしているようです。 どうすれば解決できるでしょうか。書く場所が間違っているとすればお手数ですが正しい場所をご指摘ください。

質問者が選んだベストアンサー

  • ベストアンサー
  • sygh
  • ベストアンサー率76% (42/55)
回答No.1

出されている情報があまりに少ないので回答しにくいですが、推測するに多分こうすればいいのでは? UINT __cdecl ThreadCallbackFunc(LPVOID pParam); が定義されているとして、 // サブスレッド起動後、最初はスレッドを待機させておく。 CWinThread* pThread = AfxBeginThread(ThreadCallbackFunc, NULL, 0, 0, CREATE_SUSPENDED); pThread->m_bAutoDelete = false; // 自殺はさせない。 pThread->ResumeThread(); // 手動でスレッドを再開する。 // サブスレッドが終了するまでメインスレッドは待機。 // WaitForSingleObject() の第一引数は HANDLE 型。 // スレッドのハンドルである場合、スレッドの終了によりシグナル状態になる。 ::WaitForSingleObject(pThread->m_hThread, INFINITE); delete pThread; // スレッドが終了した後で手動削除するようにしないと危険。 pThread = NULL; C#やJavaのスレッドと比べて、MFCのスレッドは全く洗練されていないので、かなり注意深くコーディングしないとすぐにハマります。 なお、質問される場合は、第三者が見てもどのシンボルが何を表しているのかがきちんと分かるように説明して、さらにVisual C++のバージョンなどの環境を明記しておいた方がいいです。

sanato
質問者

お礼

回答およびご指摘ありがとうございます。 すみません焦っていて質問内容が整理できていませんでした。 VC++2008です。 詳しい回答でとても参考になりました。 他殺の方がよいということでしょうか。 スレッドは他殺より自殺させるべきと書いていたところもありましたが、洗練されていない分、いろいろな手法があるということですね。 今現在、自殺させる方の手法のコードを見つけたのでさっそく実装し、様子を見ています。 // アプリケーション終了時 g_flag = false; do { Sleep(100); GetExitCodeThread(g_pThread, &dwExitCode); }while(dwExitCode == STILL_ACTIVE); とりあえずはこれとsyghさんの手法を見合わせて検討してみますね。

すると、全ての回答が全文表示されます。

その他の回答 (1)

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

処理スレッドの作りにもよりますが、直感的にはOnDestroyでスレッド待ち合わせを書いているのがよろしくないんではないかという気はします。 OnDestroyは呼ばれた時点で対象のウィンドウを破棄済みで、そのウィンドウに紐付くもろもろのオブジェクトも破棄されています。 ですから処理スレッド側がウィンドウにアクセスして更新するような処理だと、OnDestroy時点でも動作しようとすれば当然エラーになる、という事です。 なお、ウィンドウ破棄前のタイミングで処理する場合にはOnCloseイベントを使います。

すると、全ての回答が全文表示されます。

関連するQ&A