プロが教えるわが家の防犯対策術!

VC++6.0にてAfxBeginThreadで
m_bAutoDelete = TRUEにてスレッドをおこしております。
この終了時に制御関数のwhileループを脱する様にし、
正常にスレッドを終了させているつもりです。
この後、再度(アプリは継続して起動したまま)
AfxBeginThreadにて全く同じ処理で再開すると、
なぜか、前のスレッドが未だ動作しているかのごとく
制御関数内のTRACEが2重に出力されます。
再度、停止し、またスレッド起動すると、
今度は3重になったかの様な動作をします。

スレッドが正しく終了されていないのでは?と思った現象として、
1回起動時にアプリを終了させると正常終了しますが、
2回起動以上は必ずスレッドのメモリーリークが出ます。
メモリーリーク個所はAfxBeginThreadでした。

制御関数内で必要ないとは思いましたが、終了時に
AfxEndThreadを使用しましたが現象は同じでした。

そこで質問です。
1)この現象は、スレッドが正常に終了されていない事に起因しているのでしょうか?
2)スレッドを正しく終了させるにはどうすればいいのでしょうか?
当方、制御関数がループを抜け、さらにm_bAutoDelete = TRUEであれば
オブジェクトも自動的に破棄されると思っていたのですが。。。

以上、よろしくお願いします。

A 回答 (2件)

 こんばんは。


 AfxEndThread()で起動した物は「m_pThread->PostThreadMessage(WM_QUIT, 0, 0)」で終了させないといけないらしいです。
 http://hp.vector.co.jp/authors/VA014436/prg_memo …

 試してみましたが、此れで一応綺麗に終るようです。

CWinThread* m_pThread;
bool m_bSuspend = false;

static UINT Proc(LPVOID pData)
{
MSG msg;
CDlg* p = static_cast<CDlg*>(pData);

p->SetDlgItemText(IDC_EDIT1, "START");

while(::GetMessage(&msg, NULL, 0, 0))
{
switch(msg.message)
{
//case WM_QUIT:break;
default:;
}
}
//ココまで来ないといけない
p->SetDlgItemText(IDC_EDIT1, "END");

return 0;
}

void CDlg::OnSwitch()
{
// TODO: この位置にその他の検証用のコードを追加してください
//初めての作成
if(!m_pThread)
{
m_pThread = ::AfxBeginThread(&::Proc, this);
}
else
{
//寝ているスレッドを叩き起こす
if(m_bSuspend)
{
SetDlgItemText(IDC_EDIT1, "RESUME");
m_pThread->ResumeThread();
}
//寝かす
else
{
SetDlgItemText(IDC_EDIT1, "SUSPEND");
m_pThread->SuspendThread();
}

m_bSuspend ^= true;
}
}

void CDlg::OnExit()
{
// TODO: この位置に特別な後処理を追加してください。
if(m_pThread)
{
//寝ているスレッドを叩き起こす(寝ていなければ無視される)
m_pThread->ResumeThread();
m_pThread->PostThreadMessage(WM_QUIT, 0, 0);
m_pThread = 0;
}
}
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
原因は、制御関数内のwhile文を抜ける前に次のスレッドが起動されて
いる様で、そこで前のスレッドが正しく終了していませんでした。
スレッド停止命令後にwaitforsingleobjectにて待機させ、制御関数内のwhile文を抜けた後にseteventする処理手順を踏んだらOKでした。
ありがとうございました。
あと、PostThreadMessage(WM_QUIT, 0, 0)も試してみました。ばっちりでした。勉強になりました。

お礼日時:2008/11/30 18:09

>1)この現象は、スレッドが正常に終了されていない事に起因しているのでしょうか?


はい。

>2)スレッドを正しく終了させるにはどうすればいいのでしょうか?
>当方、制御関数がループを抜け、さらにm_bAutoDelete = TRUEであれば
>オブジェクトも自動的に破棄されると思っていたのですが。。。
「オブジェクトの破棄」と「オブジェクト内で生成したオブシェクトの破棄」はイコールではありません。
AfxBeginThreadで生成しているスレッド内で作成、もしくは実行しているオブジェクトの終了ミスか、
終了処理は行っていても、スレッド終了時までにその処理が間に合わず残っている可能性はあります。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
原因は、制御関数内のwhile文を抜ける前に次のスレッドが起動されて
いる様で、そこで前のスレッドが正しく終了していませんでした。
スレッド停止命令後にwaitforsingleobjectにて待機させ、制御関数内のwhile文を抜けた後にseteventする処理手順を踏んだらOKでした。
ありがとうございました。

お礼日時:2008/11/30 18:08

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A