スレッドが終了しない – プログラミング – Home

通知
すべてクリア

[解決済] スレッドが終了しない


aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
Topic starter  

いつもお世話になっています。よろしくお願いします。

プログラム内でスレッドを作成し、その中である処理を行っています。
スレッドの中では、通常のアプリのメッセージループと同じように GetMessage でルー
プを行い、ウィンドウプロシージャの代わりに MSG 構造体の message メンバを見て処
理を行っています。

スレッドのコードはこんな感じです。
WM_THREAD は処理を行わせるためにスレッド外から PostThreadMessage で投げる、ユー
ザー定義のメッセージです。

DWORD CALLBACK ThreadProc( LPVOID lpParameter )
{
MSG msg;
BOOL bMsg = GetMessage( &msg, NULL, 0, 0 );
while( bMsg != 0 && bMsg != -1 )
{
if( msg.message == WM_THREAD )
{
// 処理
}

bMsg = GetMessage( &msg, NULL, 0, 0 );
}

return 0;
}

このスレッドを終了させるために、スレッド外から WM_QUIT を投げ、
WaitForSingleObject で終了を待機しています。
が、何故か WaitForSingleObject がタイムアウトするまで制御が戻りません。
スレッド側では WM_QUIT を処理し、ループを抜けたのも確認しているのですが、なぜタ
イムアウトしてしまうのでしょうか?

このスレッドは DLL の DllMain 内で DLL_PROCESS_ATTACH が渡されたときに
CreateThread で起動し、DLL_PROCESS_DETACH が渡されたときに上記の終了待ちを行っ
ています。

DllMain は以下の通りです。

static HANDLE g_hThread = NULL;
static DWORD g_dwThreadID = 0;

BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvReserved )
{
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:

// (中略)
g_hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0,
&g_dwThreadID );

break;

case DLL_PROCESS_DETACH:

PostThreadMessage( g_dwThreadID, WM_QUIT, 0, 0 );
WaitForSingleObject( g_hThread, 5000 );
CloseHandle( g_hThread );

break;

default:
break;
}

return TRUE;
}

環境は WinXP Pro SP1 + VS.NET 2002 Academic です。

http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200307/03070091.txt
#こちらも回答をお待ちしています^_^


引用
トピックタグ
aetos
(@aetos)
Noble Member
結合: 6年前
投稿: 1480
Topic starter  

いつものパターン、自己レスです。すいません。

某所でこんなコメントを見つけました。
> DLL_PROCESS_DETACH時にスレッドが存在してはならない
> スレッドが、ExitThreadをコールしても、いつまでもSTILL_ACTIVEである
> どうしようもないきは、TerminateThreadで終了する

DLL_PROCESS_DETACH で終了待ちでは遅いのですね。

MSDN の CreateThread の説明にある
> 1 つのプロセスの DLL 初期化ルーチンまたは DLL デタッチルーチンの中に一度に存
在できるスレッドは、ただ 1 つです。
がいまいちよく理解できずにいたのですが、これは「現在、デタッチルーチンを実行し
ているスレッド以外は無効である」のような解釈でいいのかな?

仕方ないので TerminateThread で対処することにします。


返信引用
masaki
 masaki
(@masaki)
ゲスト
結合: 22年前
投稿: 17
 

もう解決されていますが...

> 「現在、デタッチルーチンを実行し
> ているスレッド以外は無効である」

これは、当たらずとも遠からずです。

DllMain()内のコードを実行できるスレッドは、プロセス内で1つだけで
す。
そうなるように、システムが同期を取っています。

シャノンさんのコードでは、スレッドが2つありますよね。

・WM_QUITを投げたスレッド
・WM_QUITを受けたスレッド

投げたスレッドがまだDllMain()から抜けないうちに、受けたスレッド
が終了したら、何が起こるでしょう?
システムがDllMain()を呼ぼうとしますよね。DLL_THREAD_DETACHを引数
にして。そこでロックしてしまうのです。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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