ワーカースレッド終了処理について教えて下さい – プログラミング – Home

ワーカースレッド終了処理について教えて...
 
通知
すべてクリア

[解決済] ワーカースレッド終了処理について教えて下さい


ナオーバ
 ナオーバ
(@ナオーバ)
ゲスト
結合: 23年前
投稿: 187
Topic starter  

こんにちは、ワーカースレッド終了処理について教えて下さい

void CTmpView::OnRButtonDown(UINT nFlags, CPoint point)
{
// スレッド停止
// スレッド停止
if( m_pThread ) {
m_bThreadStop = TRUE;
::WaitForSingleObject(m_pThread->m_hThread, INFINITE);
m_pThread = NULL;
}
// サスペンド状態で開始
m_bThreadStop = FALSE;
m_pThread = AfxBeginThread( ::ThreadFunc, this,
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED );
m_pThread->m_bAutoDelete = FALSE;
m_pThread->ResumeThread(); // 再開

CListView::OnRButtonDown(nFlags, point);
}

UINT ThreadFunc( LPVOID pParam )
{
CTmpView* pthis = (CTmpView *)pParam;
for( ) {
// スレッドの処理

if( pthis->m_bThreadStop ) return 0;
}
return 0;
}

スレッドの処理が終わらないうちに何回か右クリックをすると、処理が帰ってこなくなります。
WaitForSingleObjectだとは思うのですが、解決策がわかりません。

上記の記述でワーカースレッドの終了処理は正しいのでしょうか?
いろんなサイトを見て寄せ集めた記述で自信がありません。

WIN2000 SP2
VC6.0 SP5
MFC使用

よろしくお願いします


引用未解決
トピックタグ
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

終了方法は問題ないと思います。

「スレッドの処理」側からメインスレッドに
メッセージを投げたり(たとえば、CTmpViewのCWndメソッドを呼ぶ)
していませんか?
その場合、デッドロックになります。

ところで、このソースでは、
> m_pThread->m_bAutoDelete = FALSE;
としているのに、
delete m_pThread;
が無いためメモリリークしています。


返信引用
ナオーバ
 ナオーバ
(@ナオーバ)
ゲスト
結合: 23年前
投稿: 187
Topic starter  

回答ありがとうございます
前回のソースは簡単にしていたので全部書きます

UINT ThreadFunc( LPVOID pParam )
{
THREAD_INFO* stThreadInfo = (THREAD_INFO *)pParam;

CListCtrl& wndList = stThreadInfo->pthis->GetListCtrl( );
CImageList* pImgList = stThreadInfo->pthis->GetImgListPtr();
CJpegBitmap* pJpegBitmap = stThreadInfo->pthis->GetJpegBitmapPtr();
CUIntArray* puiaPhotoNum = stThreadInfo->puiaNum;
CString szPath = stThreadInfo->pDoc->GetPath();

for( int i = 0; i < puiaPhotoNum->GetSize(); i++ ) {
int nPhotoNum = puiaPhotoNum->GetAt( i ) -1;
// ファイル名取得
CString szFileName = stThreadInfo->pDoc->GetPhotoData()->GetFileName(
nPhotoNum );
CString szFilePath = szPath + PHOTO_FOLDER + szFileName;
CBitmap* pBitmap = pJpegBitmap->AddBitmapEx( szFilePath );
if( pBitmap ) {
pImgList->Replace( i, pBitmap, pBitmap );
wndList.RedrawItems( i, i );
}
// m_bThreadStopがTRUEならスレッド停止
if( stThreadInfo->pthis->GetStopFlg() ) return 0;
}
return 0;
}
ッてソースです。

この場合たくさんメインスレッドにメッセージを投げているのですが、
これが原因でしょうか?

どこかのサイトで
ワーカースレッド:ウィンドウ無し
UIスレッド  :ウィンドウあり
とあったのでワーカースレッド(AfxBeginThread)で作成しました。
もしかしてUIスレッド(CreateThread?)しなきゃだめですか?

もう一つデッドロックってどういう状態でしょう。

自分でも並行して調べますが、
よろしくお願いします。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

ワーカースレッドの使い方は間違っていません。

こちらを参照してください。
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200206/02060070.txt


返信引用
通りすがり
 通りすがり
(@通りすがり)
ゲスト
結合: 24年前
投稿: 92
 

右クリックを押して、スレッドが終了した後で、
そのスレッド内で投げ込んだ描画処理が行われているとか。


返信引用
ナオーバ
 ナオーバ
(@ナオーバ)
ゲスト
結合: 23年前
投稿: 187
Topic starter  

回答ありがとうございます。

while (WaitForSingleObject(m_pThread->m_hThread, 0)==WAIT_TIMEOUT) {
MSG msg;
if (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)) {
AfxGetApp()->PumpMessage();
}
}
を利用してうまくいきました。
メッセージポンプ?ループとか言うやつですよね。

大変参考になりました。ありがとうございます。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> を利用してうまくいきました。
> メッセージポンプ?ループとか言うやつですよね。

この場合、スレッドを待っている間も右クリックを処理して
しまうことに注意してください。
つまり、OnRButtonDown()のwhile文内でループしている間に、
右クリックすると再度OnRButtonDown()が呼び出されます。


返信引用
ナオーバ
 ナオーバ
(@ナオーバ)
ゲスト
結合: 23年前
投稿: 187
Topic starter  

ありがとうございます。

実際のソースは右クリックではなく、ツリービューのSelectItemから発生する関数です。
嘘を書いたのではありません。右クリックのイベントの方が直感的なのでそのようにしました。

ツリービューのSelectItemなので、同じ所でクリックしてもイベントが発生しない為、
ご指摘の症状はでませんでした。
ツリービューのSelectItemの最初にTRACE文を書いて確認しました。
TRACE文は実行されませんでした。
右クリックのようなイベントの時は気をつけます。フラグで何とかなるのかな?

貴重な御意見ありがとうございます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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