• 締切済み

[MFC]AfxBeginTreadでのスレッド強制終了の方法について

WinInetで多数のクライアントとHTTP通信を行うプログラムを作成しています。 やりたい事は閉じたネットワークの中で 生きているホストを調べるということです。 HTTP_GETの可否で判断させるつもりですがpingでも構いません。 (DHCPサーバーのリース情報などは参照できない状態環境) 逐次処理で一台ずつタイムアウトは待ってられないので ホストの台数分だけスレッドを作成します(クラスCなら256台分)。 <!-- コード --> UINT MyThreadProc(LPVOID pParam) {  CMyHost* hostData = (CMyHost*)pParam;  hostData->Get();  return 0; } void CMyDlg::OnStart() {  CMyHost hostData[hostNum];  CWinThread* pThread[HostNum];  // 台数分スレッド起動  for (int i=0;i<(int)HostNum;i++) {   hostData[i].ipAddr = NetworkAddress + (DWORD)i;   pThread[i] = ::AfxBeginThread(MyThreadProc, &hostData[i]);  }  // 何秒か待つ  HANDLE timer = CreateWaitableTimer(NULL, FALSE, NULL);  WaitForSingleObject(timer, 10000);  // returnしてないスレッドがあっても全スレッド強制終了  /* 強制終了の仕方が分からない */ <!-- コードここまで --> 強制終了させるためには各スレッドにメッセージを投げて スレッド側でそれを判定するなどでしょうか? でも通信の終わってないスレッドは通信処理の最中なのだから どうやってメッセージを受け取ればいいのか想像つかないです。 (そもそもCInternerSessionでタイムアウトの使い方がよく分からない…、 もっとスマートな方法があれば教えていただきたいです。)

みんなの回答

  • hiochi
  • ベストアンサー率50% (1/2)
回答No.3

WaitForSingleObjectを使っておられるようなので、WaitForMultipleObjectsを使って、終了用のイベントを追加してはいかがでしょう? 終了イベントとタイマーの両方を待っておき、終了させたいタイミングでseteventして、WaitForMultipleObjectsを抜け、抜けた後どっちのイベントだったか判断してもう一回待つなり、そのままスレッドを終了するなり処理をするイメージです。

  • BLK314
  • ベストアンサー率55% (84/152)
回答No.2

基本的なことから述べます。 通信といっても色々あります。 例えば、インターネットに公開するファイルサーバーなどで、 何MByteもあるファイルをたくさんDLさせる場合などでしたら、 アクセスが集中した場合、CPUがパンクする恐れもありますので、 特殊な技術が必要です (複数のサーバーに負荷分散するなど) しかし、一般的な機械制御とかでは、そんなに激しい通信は求められないことも 多々あります。単に機械の監視が目的なら100msec~200msecに1回通信 すればよい場合もあります すると、通信スレッドはこんな形になります   while (WaitForSingleObject(中止要求イベント, 100) != WAIT_OBJECT_0)   {      通信処理   }   前提として、"個別の通信を止める"ことはしないものとします。    止めるときは全て一斉に止めます。   個々の通信のエラー等で通信を止めたい場合は、スレッド制御関数から   returnしてください   ”中止要求イベント”は手動リセットイベントで実装します 自動にはしないでください   スレッド数に関係なく、イベントは1つで十分です   通信開始時にResetEventしてください   通信を終了したいときにSetEventします

nisecuroro
質問者

お礼

>前提として、"個別の通信を止める"ことはしないものとします。 >止めるときは全て一斉に止めます。 はい、一定時間経てば一斉に止めるようにしたいです。 >個々の通信のエラー等で通信を止めたい場合は、スレッド制御関数 >からreturnしてください それぞれのスレッドの個別の通信でタイムアウトを検出できれば returnさせれると思うのですが…CInternetSessionでのタイムアウトの指定方法、またタイムアウトの検出方法が分からないのです。 今はWinsocketで組み直しているところです。 >中止要求イベント 例えばWinSocketで実装したとして同期モードでrecv()させると そのwhileループはrecv()のところでブロックされてしまいますよね? 非同期でのやり方は調べてるのですが…まだよく分かってないです;;

  • yamaj_biz
  • ベストアンサー率71% (10/14)
回答No.1

コードをみるとワーカースレッドのようなので、メッセージを受け取る事が出来ません。(がんばれば出来ますが…) タイミングを取る場合は、イベントを使うのが手っ取り早いと思います。 また、強制終了させようとして出来ない事はないと思いますが、出来れば安全に終了させた方がいいと思います。 ワーカースレッドの場合、このコードの例でいけば「MyThreadProc」を抜けた時点でスレッドが削除されます。 pThread[i]->m_bAutoDelete = FALSE; として、自動削除しない設定にした上で、「pThread[i]->m_hThread」を集めた 「HANDLE hThread[HostNum]」を用意し、WaitForMultipleObjects 関数にて待ち合わせをするのが良いかと思われます。

nisecuroro
質問者

お礼

回答ありがとうございます。 最近帰宅したらすぐに寝てしまっていたので 返事が遅れてしまい申し訳ございません。 WaitForMultipleObjectsでスレッド自体を監視すれば良いのか… なんとなくイメージは沸いてきました。 (といってもスレッド自体よく理解してないですが)

関連するQ&A

専門家に質問してみよう