• ベストアンサー

WaitForSinbleObjectについて

こんにちは。 現在VC++6.0でスレッドを用いたプログラムを行っています。 GUIでSTARTボタンを押すと、ワーカースレッドが起動し特定量の処理を開始します。(例えば100件のファイルコピーなど) 100件の処理が完了したらワーカースレッドは終了する。 GUIでSTOPボタンを押したときにフラグを立てて、ワーカースレッド内でそのフラグが立っていたら処理を抜けてスレッドを終了させることもできるようにしたいと考えています。 このワーカースレッドの終了のことで疑問があります。 STOPボタンを押してフラグを立てたあとにWaitForSingleObjectでスレッドの終了を待とうと思っていますが、このSTOPボタンを押したタイミングと、100件のファイルコピーが終わりワーカースレッドが自分で終了するタイミングとがかぶってしまった場合、WaitForSingleObjectで待ちに入った時点で、すでにスレッドが終了してしまっている場合が起こりうるのではないかと考えているのですが、実際にどうなのでしょうか? WaitForSingleObject実行時にすでにスレッドが破棄されていた場合、WaitForSingleObjectはどういう値を返すのでしょうか? 事前にスレッド(スレッドのハンドル)が生きているかどうかを調べる方法はあるのでしょうか? ご存知の方教えてください。 わかりづらい説明で申し訳ありません。

質問者が選んだベストアンサー

  • ベストアンサー
  • googoo131
  • ベストアンサー率45% (5/11)
回答No.2

(1) 事前にスレッドが破棄されているかどうかを調べるには GetExitCodeThread() 関数を使います。 BOOL GetExitCodeThread( HANDLE hThread, LPDWORD lpExitCode ); hThread :対象のスレッドハンドル lpExitCode:終了コードを受け取る DWORD 型へのポインタ        正常終了のときは 0 以外        異常終了のときは 0 が返ります。 戻り値は、スレッドが破棄されているときはtrue、 破棄されて無いときはfalseを返却します。 <参考URL> http://wisdom.sakura.ne.jp/system/winapi/win32/win143.html (2) WaitForSingleObjectについては以下のURLを参照ください。 http://msdn.microsoft.com/ja-jp/library/cc429427.aspx GUIでスレッドの待機を行うには WaitForSingleObject 関数 ではなく、MsgWaitForMultipleObjects または MsgWaitForMultipleObjectsEx 関数 を使う指示が書かれてます。 これらについての関数仕様は以下のURLを参照ください。 ・MsgWaitForMultipleObjects 関数 http://msdn.microsoft.com/ja-jp/library/cc429261.aspx ・MsgWaitForMultipleObjectsEx 関数 http://msdn.microsoft.com/ja-jp/library/cc429263.aspx

shu0325
質問者

お礼

参考URLまでつけていただきありがとうございました。 GetExitCodeThreadで希望通りの動きをさせることができました。 アドバイスありがとうございました。

その他の回答 (1)

  • gentoo314
  • ベストアンサー率41% (15/36)
回答No.1

CreateThread() か、_beginthreadex()でスレッドを起動すると、スレッドハンドルが返り、明示的にCloseHandle()をコールする必要があります。スレッドがどのような状態でも、WaitForSingleObject()は有効です。スレッドが死んでいれば 0, 生きていればタイムアウトが返ります。下はスレッドが死ぬまで待つ例です。 Handle hThread = (HANDLE)_beginthread(...); WaitForSingleObject( hThread, INFINITE );   CloseHandle( hThread ); という具合です。

shu0325
質問者

お礼

すいません。私の説明不足でした。 スレッドの起動はAfxBeginThread()で行っています。 回答ありがとうございました。

関連するQ&A

  • スレッドについて

    スレッドについて勉強中なのですが、簡単なスレッド作り、 スレッドの処理が終わってからメインの処理を行わせたくて 以下のようなプログラムを書いてみました。 そこで、WaitForSingleObjectを使ってスレッドが終了するのを 待ちたいのですが、WaitForSingleObjectではまってしまうようで sprintfのメッセージ(スレッドが止まってしまっている)が 表示されません。 WRITE関数の処理が終われば、、WaitForSingleObjectで処理が 戻ってくると考えているのですが…。 スレッドについてと、間違いについて教えてもらえないでしょうか? 宜しくお願いします。 main { if(!stop) {   File = CreateFile(...); g_hThead = CreateThread(NULL,0,WRITE,(LPVOID)NULL,0,NULL); g_stop = false; }else { g_stop = true; ::WaitForSingleObject(g_hThead, INFINITE); CloseHandle(File); CloseHandle(hThead ); } } void WRITE() { while(!g_stop) { WriteFile(...); } ...処理を行う sprintf("スレッドを終了します。") }

  • 閉じてしまったダイアログのエディットボックスへの書き込み禁止方法

    VC++ 6.0 MFC ダイアログベースです。 メインダイアログ画面で、ボタンを押下した時に、別ダイアログ(子ダイアログ)が呼び出されて、 その子ダイアログ内では、ワーカースレッドを使用して処理を行い、 処理結果をエディットボックスに表示させています。 子ダイアログを閉じる時に、WaitForSingleObject を使って、スレッドを完全に終了させてからダイアログを閉じるように しているのですが、スレッドの処理が、エディットボックスに書き込む時に閉じてしまうと、 スレッドがそこで止まってしまいスレッドが終了しません。 このような場合どうしたら良いのでしょうか? ・閉じるボタンが押されたら、エディットボックスに書き込まないようにすれば良いと思い、 (フラグを立てて試したのですが、フラグチェック後に閉じるが押されることがあり失敗) // スレッドの開始 m_Thread = AfxBeginThread(ThreadFunc, this);    // この時、子ダイアログを閉じてしまうと // INFINITEなので、ずっと止まってしまいます。 CString data = "処理結果"; case 0: m_M0edit.SetWindowText(data); break; case 1: m_M1edit.SetWindowText(data); break; case 2: m_M2edit.SetWindowText(data); break; ・ ・ ・ ・ // 子ダイアログを閉じる時に呼び出されます。 // スレッドでの処理が完全に終わるのを待ちます。 afx_msg void CSelecting_Dlg::OnClose() {   DWORD dwRet   dwRet = WaitForSingleObject(m_Thread->m_hThread, INFINITE);   EndDialog(0); } /***************/ 失敗談 /***************/ // スレッドの開始 m_Thread = AfxBeginThread(ThreadFunc, this);    // この時、子ダイアログを閉じてしまうと // INFINITEなので、ずっと止まってしまいます。 CString data = "処理結果"; if (m_openFlag == 1){ //フラグを見て書き込みするかチェックする。   switch (t){      case 0: m_M0edit.SetWindowText(data); break;      case 1: m_M1edit.SetWindowText(data); break;      case 2: m_M2edit.SetWindowText(data); break; ・ ・ ・ ・   } } // 子ダイアログを閉じる時に呼び出されます。 // スレッドでの処理が完全に終わるのを待ちます。 afx_msg void CSelecting_Dlg::OnClose() {   DWORD dwRet   m_openFlag = false; //閉じるボタンが押されたら フラグを降ろす。   dwRet = WaitForSingleObject(m_Thread->m_hThread, INFINITE);   EndDialog(0); }

  • マルチスレッド内のループについて

    こんにちは。 開発環境は VC++6.0 SDI マルチスレッドがあり、2つの処理を行う関数が書かれています。 このスレッドはダイアログボックスに配置したストップボタンを押すとフラグFALSEになりループを終了させます。 2つの関数は、int型の整数を引数にして、処理を行います。 整数はある値に達すると 0 になり永遠にループを続け、2つの処理を行います。 と言う意味合いでプログラムを書きました。(書いたつもりです) (1)この書き方ですと、for内のループが動いている時に、右上の×ボタンでダイアログを閉じると [Debug Assertion Failed!]と言う警告文が出て強制的に終了してしまいます。 ストップボタンを押してもcount=10になるまではループしています。(当然ですが・・。) そもそもマルチスレッドの中にこのような形でfor文を入れるのは間違っているのでしょうか? どのような書き方にすれば良いのでしょうか? よろしくお願い致します。 bool m_flags;//スレッド内の処理を続けるか示すフラグ UINT CabcDlg::thread(LPVOID pParam)// { CabcDlg *pInst = (CabcDlg *) pParam; while(pInst->m_flags){//ストップボタンが押されると終了する。 for (int count = 0; count<10; count++ ) { pInst->OnSend(count); //処理A pInst->OnReceive(count);//処理B } } return 0; }

  • VC++ Workerスレッドを強制終了させる方法

    VC++6.0でwinアプリを作っています。 ダイアログベースで、ボタンを押すとワーカースレッドを実行し、ここでデータ処理をしています。 もし、スレッド中でデータ処理時間がかかってしまうと、これをスレッド外で強制的に終了させたいですが、出来るのでしょうか。 よろしくお願いします。

  • スレッド終了を待つ間に開放されたデータを参照

    MFCのアプリケーションで、 マルチスレッド処理中にユーザがアプリを終了できる場面があります。 スレッドの末尾にフラグを置き、 それがOFFなら抜ける、というコードを書いているのですが、 そこにたどり着くまでに、開放されたデータ等を参照してエラーが発生します。 CMainFrame::OnDestroy() の先頭でフラグをOFFにし、 ::WaitForSingleObject(pThread, INFINITE); を書いたのですが、素通りしているようです。 どうすれば解決できるでしょうか。書く場所が間違っているとすればお手数ですが正しい場所をご指摘ください。

  • CSocket通信での待機処理について

    VC++2008にて、サーバとクライアントPCにて、相互通信を行うプログラムを作成しています。 クライアントは、CSocketを利用しマルチスレッドにて通信を行っています。 thread_start→マルチスレッド作成→ CSocket::Sendでサーバへメッセージ送信→ CSocket::OnReceiveでサーバのメッセージ受信→ サーバメッセージから処理実行と言った流れです。 通常の処理は、この流れで問題ないのですが、 ある処理の場合、thread_startをforループで数回繰り返す 処理を行っています。 この時、データにタイムラグが出てしまうため、 thread_startから処理実行までの一連の流れが終了するまで、 次のthread_startは呼ばれずに待機させたいのですが、 どのようにすれば良いのかが分かりません。 Sendを呼んだタイミングで、 WaitForSingleObjectでスレッドのハンドルを渡したり、 CreateEventでイベントハンドルを渡したりしてみたのですが、 WaitForSingleObjectを呼ぶと、OnReceiveで受信する前で 止まってしまうため、そのままフリーズ状態になってしまいます。 どのタイミングでWaitFor~を呼ぶべきなのか、 もしくは、何か別の手段があるのでしょうか?

  • 携帯のjavaでthreadを強制中断するには

    携帯のjavaでthreadを強制中断するには javaの thread には stop() で強制的に処理を止めることができると思いますが、携帯(DoCoMo)のjava では stop() が使えないのでしょうか? 携帯で思考をしている thread が一定以上時間がかかってしまったなら、諦めて中断させたいのですが。 今は、stop()が使えないので、中断フラグを使って中断させていますが、複雑な思考のなかで、いろいろな所に中断フラグを監視しなければならず、たいへん面倒です。 なにかうまい方法をご存知ならご教授ください。

    • ベストアンサー
    • Java
  • WaitForSingleObject()でエラー

     初めまして、自分の知識不足で解決できないため、こちらに質問をさせてもらいます。  自分が保守をしているプログラムでエラーが出ているのですが、原因が分からず行き詰っています。  対象のプログラムは、マルチスレッド構成で、プログラム終了時にメインスレッドが他のスレッドをWaitForSingleObject()でチェックして全てのスレッドが終了していたら自分も終了してプログラムを終わらせています。  この時、あるスレッドへのWaitForSingleObject()で「WAIT_FAILED」が返り、GetLastError()で取得したエラーコードが「5:アクセス拒否」でした。  エラー自体も毎回起きるわけではなく、しかも同一の筐体では発生していないので、タイミング的な問題ではないかと考えているのですが、WaitForSingleObject()でこんなエラーが返るのは初めてで、お手上げ状態になっています。  プログラムは、C言語で作成しており、WindowServer2003/VisualStudio2005の環境からWindowsServer2012/VisualStudio2012にリコンパイルして動かしており、2003環境ではおきたことがなく、2012環境になってから発生しています。  チェック先のスレッドも、タイミング的にはスレッドで保持しているメモリをクリアした後に_endthread()を実行しているだけでなのですが、わな掛けとかしたくてもどこにすれば良いのか分からず、ここに質問をさせてもらいました。  どんなヒントでも良いので、アドバイスがあればお願いします。

  • タイマー関数とマルチスレッドについて

    こんばんわ。 マルチスレッドプログラミングを行なっています。 コンパイラはVC++.NETでC言語を利用しwin32 apiを用いています。 スレッドを_beginthreadex関数でスレッドを2つ生成し、WaitForSingleObject,SetEvent,ResetEvent関数によるイベント同期を利用し、2スレッドの同期をはかっています。 [質問内容] 以下のように、スレッド2でWaitForSingleObject関数にてスレッド2を待機状態にし、スレッド1のSetEvent関数にて待機しているスレッド2を再開させる方法をとっています。 例えば、タイマーをスタート後に待機状態になり、スレッド2が再開後タイマーストップするとした場合、スレッド2が待機状態のときもタイマーを動き続けているのでしょうか? ・スレッド1 SetEvent(hEvent[0]); ・スレッド2 SUSPEND_INTERVAL=20 if(Num%THREAD_SUSPEND_INTERVAL==0){ timestart=timeGetTime();←タイマースタート WaitForSingleObject(hEvent[0],INFINITE); ResetEvent(hEvent[0]); timestop=timeGetTime();←タイマーストップ } よろしくお願いします。

  • 「UIスレッド」「マルチスレッド」の違い

    Androidで、「UIスレッド」「マルチスレッド」の違い、を教えてください。 ■下記理解で合ってるでしょうか? Androidは、「シングルスレッド」の「UIスレッド」モデルなので、それを「マルチスレッド」で動かそうとすると、「ワーカースレッド」で処理する必要がある ・「マルチスレッド」=「マルチタスク」? ・「UIスレッド」とは、メインスレッドが「GUI (グラフィカルユーザーインターフェイス) 処理」を行うものを指す? ・つまり、「Android」=「UIスレッド」? ・「UIスレッド」って何の用語? Androidに特化した用語? それともJAVAの用語? あるいはそれ以外?

    • ベストアンサー
    • Java

専門家に質問してみよう