スレッドで稀にタイムアウトになってしまう – プログラミング – Home

スレッドで稀にタイムアウトになってしま...
 
通知
すべてクリア

[解決済] スレッドで稀にタイムアウトになってしまう


いっし
 いっし
(@いっし)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

VC++6なんですが
IMPLEMENT_DYNCREATE(AAA_Thread, CWinThread)

BOOL AAA_Thread::InitInstance()
{
いろんな処理
return FALSE; ←でスレッドを終了
}

int AAA_Thread::ExitInstance()
{
終了処理
iRet = CWinThread::ExitInstance();
return iRet;
}

こんな感じのスレッドクラスが2つあります。(もうひとつはBBB_Threadとします)

メインの処理でAfxBeginThreadをしてm_bAutoDelete = FALSE;をして
ResumeThread();で開始します。

とあるタイミングでAAA_ThreadとBBB_Threadのスレッドを何回か開始しては
WaitForSingleObjectで待って終わったらまた開始という感じで処理をするのですが
ごく稀にWaitForSingleObjectでタイムアウトになってしまいます。
タイムアウト時間はかなり余裕があります。
ログを見るとスレッドクラスのInitInstanceの最後の処理までは
終わっているみたいなのですがなぜかWaitForSingleObjectでタイムアウトか
返ってきます。
作り的には問題ないでしょうか?
何か原因があるのでしょうか?
以上よろしくお願いします。


引用未解決
トピックタグ
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> メインの処理でAfxBeginThreadをしてm_bAutoDelete = FALSE;をして
> ResumeThread();で開始します。
ワーカスレッドじゃないと思うのですが、通常起動ではだめなんですか?

> BOOL AAA_Thread::InitInstance()
> {
> いろんな処理
> return FALSE; ←でスレッドを終了
> }
普通こういう処理はしません。
>return FALSE;
は初期化に失敗したときだけです。
WaitForSingleObjectで待っているのとInitInstance()で処理するとき
が合ってないとか。
InitInstance()を抜けた後、WaitForSingleObjectで待っていすと
いうことはないですか?


返信引用
いっし
 いっし
(@いっし)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

MFCでユーザーインターフェイススレッドとして作ってありますので
AfxBeginThreadで問題ないと思います。(MFC以外ならCreateThreadなどかな・・?)

>普通こういう処理はしません。
>return FALSE;
>は初期化に失敗したときだけです。

そんな気はしていたんですが・・初期化に失敗したら
WaitForSingleObjectでタイムアウトという訳でも・・

>InitInstance()を抜けた後、WaitForSingleObjectで待っていすと
>いうことはないですか?

動き的にはもうスレッドがInitInstance()を抜けて終わってから
WaitForSingleObjectで待つという形になっています。
スレッドがInitInstance()を抜けて終わっているので
通常はWaitForSingleObjectでタイムアウトではなく
WAIT_OBJECT_0が返ってきています。


返信引用
rin
 rin
(@rin)
ゲスト
結合: 18年前
投稿: 112
 

スレッド作成・起動部分、WaitForSingleObjectによる待機部分のソースを
提示してみてはどうでしょうか?


返信引用
いっし
 いっし
(@いっし)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

//スレッドを生成~開始
CAAA_Thread *A_pThread;
A_pThread = (CAAA_Thread*)AfxBeginThread(
RUNTIME_CLASS(CAAA_Thread),
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
A_pThread->m_bAutoDelete = FALSE;
A_pThread->ResumeThread();

//スレッド終了待ち
dwRet = ::WaitForSingleObject(A_pThread->m_hThread, (100 * 1000));
if(dwRet == WAIT_TIMEOUT) {
ログからここに入っていた
}

ログからInitInstanceは最後まではスレッド終了待ちの前に行っているので
ExitInstanceでフリーズしているのかもしれません。
処理的に止まりそうなところは無いと思うのですが・・
(超極稀にしか発生しないってのが難しいところです)

int CAAA_Thread::ExitInstance()
{
int iRet;
try{
 if(this->COMオブジェト != NULL) {
this->COMオブジェト.Release();
this->COMオブジェト = NULL;
 }
} catch(...) {
//無視
}
CoUninitialize(); (InitInstanceの中でCoInitialize(NULL)やCOMオブジェクト生成)

iRet = CWinThread::ExitInstance();
return iRet;
}

たぶんスレッド自体には問題なさそうなんでどっかで何か壊しちゃっているのかも
しれませんね・・・


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

> A_pThread->m_bAutoDelete = FALSE;
CAAA_Threadのオブジェクトが終了しないとだめだとおもいますが?
ユーザーインターフェイススレッドの時は設定しないほうがいいと思います。

> dwRet = ::WaitForSingleObject(A_pThread->m_hThread, (100 * 1000));
このやりかたはワ-カスレッドの時だと思います。
ExitInstance()時にSetEventで処理したうハンドルを
使ったほうがいいとおもいます。


返信引用
いっし
 いっし
(@いっし)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

>CAAA_Threadのオブジェクトが終了しないとだめだとおもいますが?
>ユーザーインターフェイススレッドの時は設定しないほうがいいと思います。
自動廃棄するとA_pThread->m_hThreadが参照できなくなるので
まずいのではないでしょうか?

AfxBeginThreadの場合はWaitForSingleObjectではなく
GetExitCodeThreadでないと失敗する場合があるということを聞きました。
調べましたが事例が見つかりませんでしたが
心当たりあるかたはおりませんでしょうか?
とりあえずGetExitCodeThreadによる終了判定にしようと思います。


返信引用
いっし
 いっし
(@いっし)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

気づくのが遅れましたが
ExitInstance()でSetEventでやる場合には
自動廃棄でよさそうですね。


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

> A_pThread->m_bAutoDelete = FALSE;
こうすると、オブジェクトだけが破棄されずに残るみたいですね。
ワーカスレッドとは違うみたいです。

> AfxBeginThreadの場合はWaitForSingleObjectではなく
> GetExitCodeThreadでないと失敗する場合があるということを聞きました。
AfxBeginThreadの戻り値は「CWinThread」のポインターです。
ですから、戻り値を記憶して、「CWinThread」のポインターのハンドルを
利用しないといけないと思います。
MFCのスレッドの終了方法の説明でGetExitCodeThreadの使い方が書いてあります。

>とりあえずGetExitCodeThreadによる終了判定にしようと思います。

> ExitInstance()でSetEventでやる場合には
> 自動廃棄でよさそうですね。
これが、ユーザーインターフェイススレッドの場合の方法だと思います。

1. SetEventのハンドルをWaitForSingleObjectで待つ。
2. GetExitCodeThreadで終了判定する。
の手順でいいと思います。
2.は駄目押しです。
何か複雑な処理をしていれば別ですが、
Sleepで一定時間待てばいいと思います。


返信引用
いっし
 いっし
(@いっし)
ゲスト
結合: 16年前
投稿: 6
Topic starter  

いろいろありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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