• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:スレッドの再開)

スレッドの再開

このQ&Aのポイント
  • MFCでアプリケーションを開発し、計算処理を行うために別スレッドを生成する方法について質問です。
  • OnInitDialog()でイベントとスレッドを生成し、スタートボタンのクリックで計算処理を呼び出しています。
  • タイマーを使用して一定時間ごとにスレッドを再開し、計算処理を実行しますが、初回のみ計算処理が呼び出され、その後はスレッドが再開されません。どこを修正すれば良いでしょうか。

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

  • ベストアンサー
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.1

ResumeThreadは停止したところから再開するだけです。 最初から実行しなおしてはくれません。 スレッド側をループにするなどする必要があると思います。 SuspendThread、ResumeThreadは使わず、 ループにしたうえで、同期オブジェクトとWaitForSingleObjectとかを使うのがいいのかなと思いますが、処理の詳細がわかりませんので、細かいところは調べて検討してください。 あと、MFCですので、AfxBeginThreadのほうがいいように思います。 MFCを使っていたのはずいぶん前の話なので、事情が変わっていましたら、申しわけありません。

umiushi21
質問者

お礼

ご回答ありがとうございます。 >ResumeThreadは停止したところから再開するだけです >最初から実行しなおしてはくれません。 このあたりが全くわかっていませんでした。 スレッドを最初から実行したいタイミングごとに、AfxBeginThread()をする必要があるという解釈で正しいでしょうか? CreateThread()をAfxBeginThread()に修正し、タイマー呼び出しごとにAfxBeginThread()を実行することで繰り返し計算処理(Run())を呼び出せるようになりました。 終了時の処理などがまだ怪しいですが、こちらも追々調べてみようと思います。 ありがとうございました! ---------------------------------------------------------------- ※修正後コード BOOL CMFCApplication1Dlg::OnInitDialog() {   CDialog::OnInitDialog();   中略   …   m_hEvent = CreateEventA(NULL, FALSE, FALSE, "EVENT");   return TRUE; } void CMFCApplication1Dlg::OnTimer(UINT_PTR nIDEvent) {   switch(nIDEvent)   {   case 1:     {       if(m_pLineProThread == nullptr)       {         m_pLineProThread = AfxBeginThread(ThreadProc, (LPVOID)this, THREAD_PRIORITY_NORMAL, 0, 0, NULL);         ASSERT(m_pLineProThread);         if(m_pLineProThread)         {           m_pLineProThread->m_pMainWnd = this;           m_pLineProThread->m_bAutoDelete = TRUE;         }       }       BOOL blRet = SetEvent(m_hEvent);     }     break;   default:     {     }     break;  }   CDialog::OnTimer(nIDEvent); } UINT CMFCApplication1Dlg::ThreadProc(LPVOID pParam) {   CMFCApplication1Dlg* pDlg = dynamic_cast<CMFCApplication1Dlg*>(reinterpret_cast<CWnd*>(pParam));   if(pDlg)   {     pDlg->ThreadProcCall();   }   return 0; } // LineProfileスレッド処理呼び出し. void CMFCApplication1Dlg::ThreadProcCall(void) {   // イベント待機.   WaitForSingleObject(m_hEvent, INFINITE);   // 非シグナル状態に.   ResetEvent(m_hEvent);   // 計算処理呼び出し.   Run();   this->SendMessage(WM_USER_COMPLETE_PROC); } void CMFCApplication1Dlg::Run(void) {   // 計算処理. } // LineProfileスレッド終了後処理. afx_msg LRESULT CMFCApplication1Dlg::OnCompleteProc(WPARAM wParam, LPARAM lParam) {   m_pLineProThread = nullptr;   return 0; } void CMFCApplication1Dlg::OnBnClickedBtnStart() {   // 計算処理呼び出し用タイマー設定.   SetTimer(1, 500, NULL); }

その他の回答 (1)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

>タイマー呼び出しごとにAfxBeginThread()を実行することで リソースや計算結果を使いまわし等を特にしないのであれば、それで問題ないと思います。 計算開始にEventをつかっていますが、AfxBeginThread()でCREATE_SUSPENDED を指定して、m_pMainWnd 、m_bAutoDeleteを設定後、CWinThread::ResumeThread()でスレッドの実行を開始するほうがスマートかと思います。 https://msdn.microsoft.com/ja-jp/library/s3w9x78e.aspx

umiushi21
質問者

お礼

引き続きご回答頂きありがとうございました。 確かにこの場合イベントを使用する必要がないですね。 Event起動から、CWinThread::ResumeThread()に変更しました。 この度は丁寧なご回答ありがとうございました、大変助かりました。

専門家に質問してみよう