重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

MFCのアプリケーションで、
マルチスレッド処理中にユーザがアプリを終了できる場面があります。
スレッドの末尾にフラグを置き、
それがOFFなら抜ける、というコードを書いているのですが、
そこにたどり着くまでに、開放されたデータ等を参照してエラーが発生します。

CMainFrame::OnDestroy()
の先頭でフラグをOFFにし、
::WaitForSingleObject(pThread, INFINITE);
を書いたのですが、素通りしているようです。

どうすれば解決できるでしょうか。書く場所が間違っているとすればお手数ですが正しい場所をご指摘ください。

A 回答 (2件)

出されている情報があまりに少ないので回答しにくいですが、推測するに多分こうすればいいのでは?




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++のバージョンなどの環境を明記しておいた方がいいです。
    • good
    • 0
この回答へのお礼

回答およびご指摘ありがとうございます。
すみません焦っていて質問内容が整理できていませんでした。
VC++2008です。

詳しい回答でとても参考になりました。
他殺の方がよいということでしょうか。
スレッドは他殺より自殺させるべきと書いていたところもありましたが、洗練されていない分、いろいろな手法があるということですね。
今現在、自殺させる方の手法のコードを見つけたのでさっそく実装し、様子を見ています。

// アプリケーション終了時
g_flag = false;
do
{
Sleep(100);
GetExitCodeThread(g_pThread, &dwExitCode);
}while(dwExitCode == STILL_ACTIVE);

とりあえずはこれとsyghさんの手法を見合わせて検討してみますね。

お礼日時:2011/01/21 22:29

処理スレッドの作りにもよりますが、直感的にはOnDestroyでスレッド待ち合わせを書いているのがよろしくないんではないかという気はします。


OnDestroyは呼ばれた時点で対象のウィンドウを破棄済みで、そのウィンドウに紐付くもろもろのオブジェクトも破棄されています。
ですから処理スレッド側がウィンドウにアクセスして更新するような処理だと、OnDestroy時点でも動作しようとすれば当然エラーになる、という事です。

なお、ウィンドウ破棄前のタイミングで処理する場合にはOnCloseイベントを使います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!