• ベストアンサー

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

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

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

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

>これをスレッド外で強制的に終了させたい とういうことですが、もしこれを行うと、強制終了させられたスレッドは正規の終了手続きを踏まずに終了します。 そのため、確保したリソースの解放漏れ等が発生しますので、できたらしない方が良いと考えます。 最も簡単な方法は、(ワーカスレッドの作り方にも依存しますが)、フラグによる制御です。 ボタンが押された時、メインスレッドがフラグをオンします。(最初はオフ) ワーカスレッドは一定間隔(ループしているならループの途中で)で、フラグがオンかどうかをチェックし、オンの場合は自らすみやかに終了するようにします。

jaekuk
質問者

お礼

ご回答有難うございます。 前後の状況を見ましたら、tatsu99さんのおっしゃった通り、確保したメモリが正しく解放されない問題が発生することが分かりました。 教えて頂いたように、フラグで制御しようと思います。 有難うございました。

その他の回答 (2)

noname#9119
noname#9119
回答No.2

スレッドを「強制的に」終了させるには TerminateThread 関数を使う。 「強制的に」終了させるのでヘルプにも「危険な関数」などと書かれていたりするけれども、 問いは「強制的に終了させたい」だから、これでいいよね?

回答No.1

できます。 問いは「できるのでしょうか」だから、これでいいよね?

jaekuk
質問者

補足

ご回答有難うございます。 出来るならば、方法を教えていただけませんか。 可能でしたらソースコードもお願いします。

関連するQ&A

  • スレッドの作成と起動

    <プログラム環境> Windows XP VC++6.0 MFC AppWizard(exe) ダイアログベース <質問> ボタンを押すとOnButton()に入ります。 OnButton()内でワーカースレッドを起動させたいのですが、 どのようにコーディングするのでしょうか? スレッドの作成方法も分かりません・・。 宜しければご指摘お願い致します。

  • VC++6.0 異常終了の調査方法

    環境:VC++6.0 MFC使用 ダイアログベースアプリケーション 使用PC:同一ソースをWin2000またはWinXPでリビルドして使用 です。 メインダイアログにメニューを実装し、あるメニュー項目を 選ぶと別のダイアログをDoModalで表示し、別のダイアログで「OK」を 押すとメインダイアログに処理が戻るようなソフトを作成しています。 別のダイアログは数種類あり、EDITボックスやコンボボックスなどを 配置しています。 ダイアログ切り替えの運用試験として、 あるダイアログを表示→閉じるを繰り返す試験を行っていると、 数時間でこのソフトが異常終了してしまいます。 (タイマ処理内で、現在日時分秒を出力しています) 「あるダイアログを表示」は、ソフトのタイマ処理で5秒おきにDoModalしています。 「閉じる」は、「OK」ボタンを押す別アプリを作成しています。 別アプリでは、「IsWindowVisible()の戻り値がTRUE」かつ 「FindWindowExを使用してlpszWindow(ウインドウ名)が「OK」」 のコントロールを探し出し、見つかればSendMessageなどで 「OK」ボタンを押す処理を代行させています。 何が原因で異常終了してしまうかを調べたいのですが、 具体的な良い方法はありませんでしょうか。 わかっている現象として、 1.タスクマネージャのプロセスタブで このソフトのメモリ使用量を見ていると、 時間とともに少しずつ増加しています。 よろしくお願いいたします。

  • VC++スレッドの正しい終了のさせかた

    VC++6.0にてAfxBeginThreadで m_bAutoDelete = TRUEにてスレッドをおこしております。 この終了時に制御関数のwhileループを脱する様にし、 正常にスレッドを終了させているつもりです。 この後、再度(アプリは継続して起動したまま) AfxBeginThreadにて全く同じ処理で再開すると、 なぜか、前のスレッドが未だ動作しているかのごとく 制御関数内のTRACEが2重に出力されます。 再度、停止し、またスレッド起動すると、 今度は3重になったかの様な動作をします。 スレッドが正しく終了されていないのでは?と思った現象として、 1回起動時にアプリを終了させると正常終了しますが、 2回起動以上は必ずスレッドのメモリーリークが出ます。 メモリーリーク個所はAfxBeginThreadでした。 制御関数内で必要ないとは思いましたが、終了時に AfxEndThreadを使用しましたが現象は同じでした。 そこで質問です。 1)この現象は、スレッドが正常に終了されていない事に起因しているのでしょうか? 2)スレッドを正しく終了させるにはどうすればいいのでしょうか? 当方、制御関数がループを抜け、さらにm_bAutoDelete = TRUEであれば オブジェクトも自動的に破棄されると思っていたのですが。。。 以上、よろしくお願いします。

  • スレッドの終了コード

    VC6.0でダイアログアプリケーションを作成しています。 デバッグモードで終了させると、アウトプットウィンドウに  スレッド 0x1124 終了、終了コード 0 (0x0)。  スレッド 0x1408 終了、終了コード 0 (0x0)。  スレッド 0x1118 終了、終了コード -1 (0xFFFFFFFF)。  スレッド 0x108C 終了、終了コード 0 (0x0)。 という内容が出力されるのですが、 終了コードが-1というのは異常終了になりますか? その場合、スレッド0x118を特定することはできるでしょうか? よろしくお願いいたします。

  • スレッド処理からダイアログを表示するには?

    Windows XPとVC++ 6.0で 時間のかかる大量の計算をするプログラムを作っています。 計算部分はスレッド処理にして 進捗ダイアログ(CDialogにCProgressCtrlを貼り付けたもの) を表示します。 ・CWinAppのInitInstanceで計算処理開始(AfxBeginThread) ・計算処理内で進捗ダイアログをCreate ・計算の進み具合によって進捗ダイアログのプログレスバーを更新 上記の流れではうまくいっていたのですが 以下のように変更したところ、進捗ダイアログをCreateするところで プログラムが応答なしになってしまうようになりました。 ・メインダイアログ(モーダル) ・メインダイアログのAボタンクリックでダイアログAを開く(モーダル) ・ダイアログAの実行ボタンクリックで計算処理開始(AfxBeginThread) ・計算処理内で進捗ダイアログをCreate ・計算の進み具合によって進捗ダイアログのプログレスバーを更新 MFC Wizardでダイアログベースで作成、MFCの共有DLLを使用しています。 モーダルダイアログ→スレッド→CDialog.Createに 制限があったりするのでしょうか。 どうかご教授ください。

  • VC++2005のスレッド使用方法について

    現在、VC++2005 SP2にてDLLを作成しています。 DLLには一つスレッドがあり、開始関数が実行されれば、スレッドが起動。終了関数を実行すればスレッドを停止させたいと思っております。 関数を分けていますので、以下の内容をグローバルで宣言したいと考えています。 Thread^ oThread = gcnew Thread( gcnew ThreadStart( &CUart::ThreadProc ) );                                     ~~~~~~~~~~~~~~~~~~~~~~~~                                         実行関数です。 oThread->Start();  //開始関数のスレッド開始  oThread->Abort();  //終了関数のスレッド停止 現在、宣言をグローバルのところに配置して、ビルドすると エラー 1 error C3145: 'oThread' : グローバルまたは静的変数は、マネージ型 'System::Threading::Thread ^' を含むことはできません とエラーが発生してしまいます。 いろいろ調べましたが、なかなか進んでいない状態です。 使用方法が間違っているのでしょうか?申し訳ありませんが、教えてください。 もし、別の方法があればご教授願います。 よろしくお願いします。

  • WaitForSinbleObjectについて

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

  • [VC++] AfxBeginThreadで生成したスレッドの監視方法について

    お世話になります。 VC++でスレッドプログラムを作っています。 AfxBeginThreadでワーカースレッドを作成し、その中でダイアログを表示する プログラムです。 問題は、ワーカースレッドがある処理状態に至ったことを メインスレッドで検知したいのですが、それがうまく いかないということです。 コードの概略をしめします。 <メインスレッド側> void CTestApp::OnTest() {   CTestDlg dlg;   dlg.IsContinue = FALSE;   pThread = AfxBeginThread(TestDlg::Thread, (void*)&dlg);   while (!dlg.IsContinue) { // <----問題:このループ処理を抜けれない!    Sleep(0);   } } <ワーカースレッド側> UINT TestDlg::Thread(LPVOID pParam){   TestDlg* pDlg = (TestDlg*)pParam;   pDlg->Create(TestDlg::IDD);   pDlg->ShowWindow(SW_SHOW);     pDlg->IsContinue = TRUE; //<--ここでフラグを変更しているのに。   while(pDlg->IsContinue) {    MSG msg;    if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {      ::TranslateMessage(&msg);      ::DispatchMessage(&msg);    }   }   pDlg->DestroyWindow();   return 0; } ---- メインスレッドのSleep(0)で待つのを AfxGetApp()->PumpMessage()に変更すると ループを抜けるようなのですが、どうも納得できません。 上記のプログラムで問題、もしくはプロジェクトの 設定等に不備がある可能性がありましたら 御教授いただけたら幸いです。 よろしくおねがいいたします。

  • モーダルとスレッド

    JOptionPaneでダイアログを出力する直前に新しいスレッドを作っておき、 その中でバックグラウンド用処理を行いたいと思っています。 色々ためしたのですが、ダイアログの了解ボタンを押すまで新たに作った スレッド内のバックグラウンド処理もブロックされる様です。 (スレッドのプライオリティ等も変更してみました。) モーダル画面を起動するとその画面が終了するまで、そのプロセス内の 全てのスレッドがブロックされるという事なのでしょうか? (勿論、モーダル画面からの入力受付となるEventDispatchThreadは動いて いるのでしょうけど) もし、「そうである」ならば、JOptionPaneはあきらめて、モードレスダイアログ を作成しようと思いますし、「いや、こういう手段がある」というのなら それを教えてください。 以上、よろしくお願いします。

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

    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); }

専門家に質問してみよう