- ベストアンサー
無限ループの防ぐ方法
- 無限ループの発生を防ぐための対応方法として、delay関数を利用する方法があります。
- ただし、delay関数を利用すると処理が重くなる可能性があるため、最小限の改造で解決する方法を検討する必要があります。
- 他の処理も含めて改造をすることで、PCのフリーズを防ぐことができる可能性があります。
- みんなの回答 (10)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
UNIXについては全く詳しくありませんが・・・ 無限ループ内で一定ループや一定時間ごとにCPU使用率を調べ、一定以上になっていたらdelayする、みたいなのは駄目でしょうか? 具体的にはループ内で一定ごとに/proc/loadavgでcpuの利用率を得て何とかする、みたいな感じでいけないかと。/proc/ ↓Linuxでの/procの解説ページですが、参考までに。 http://www.atmarkit.co.jp/flinux/special/proctune/proctune01b.html 検索かけて回答しただけなので、自分でも良く分かっていません。ちんぷんかんぷんな事を言っていたら無視してください。
その他の回答 (9)
- Interest
- ベストアンサー率31% (207/659)
> QNX Software Systemsと言ったリアルタイムOS(UNIX系)を > 使っており。 開発言語はC言語です。 そのRTOSを使ったことは無いのですが、マルチスレッドのプログラムを書く場合、一般的にはこんな風に書きます。 ------------------------------- (イベントフラグを使った例) while(1){ wait_event( event_flag ); // OSが提供する同期通信機能 switch( event_flag ){ case EVENT_A: (省略) } } ------------------------------- 同期通信機能には、 - イベントフラグ - セマフォ(ロック、ミューテックスとも言う) - メールボックス - データキュー 等々があり、用途に応じて使い分けます。 おそらく、QNXの仕様書をみれば使用可能な同期通信機能に関する記載があると思いますので、それを使ってみてはいかがでしょうか。
- titokani
- ベストアンサー率19% (341/1726)
C/C++は言語使用レベルでマルチスレッド/マルチタスクをサポートしていません。なので、こういった話はOSによって対処が違います。 delayという関数も標準の関数ではありませんしね。 気長に「QNX Software Systems」を使っている人が現れるのを待つよりは、メーカーのサポートに問い合わせたほうが早そうです。 http://www.qnx.co.jp/ フォーラムもあるみたいですよ。 http://community.qnx.com/sf/projects/qnx-j-community
お礼
回答ありがとうございます。 色々な、情報ありがとございます。 是非とも参考にさせていただきます。
- yama1718
- ベストアンサー率41% (670/1618)
ループの中にdoEventsを入れるのはどうですか? http://homepage2.nifty.com/kasayan/vba/doevents.htm http://oshiete1.goo.ne.jp/qa2008316.html ただし、これは昔のWin95や98の擬似マルチタスクだった頃に有効だった手段ですが。 今のXPなどは完全なマルチタスクなので無意味かもしれません。
お礼
回答ありがとうございます、環境の説明不足でした。 QNX Software Systemsと言ったリアルタイムOS(UNIX系)を 使っており。 開発言語はC言語です。
- zwi
- ベストアンサー率56% (730/1282)
共通のサブルーチンを1つ作って、そのサブルーチンが一定回数呼ばれるごとにdelayするんじゃだめですかね? 色んなスレッドから呼ばれる場合は、スレッドごとに回数カウンタをパラメータで渡してやらないとまずいとは思いますけど。
お礼
回答ありがとうございます、私もその案を考えていました。 そのサブルーチンが一定回数呼ばれるごとにdelayを行い フリーズを防止する、その後ログを残すって言う感じです。 しかし、zwiさんもおっしゃる通り色んなスレッドから呼ばれる 状態で困っています。 しかもそのスレッドがサブルーチン だったりするから困り物です。 プロセスID、引数など・・・etc 検討しています。 ありがとうございました。
- hidebun
- ベストアンサー率50% (92/181)
実行タイミング制御が適切に行われていないように見えるので、「処理が重くなる」の判断基準については、よくわかりません。 メインの処理を見ると、ループ変数の値で処理フラグが制御されているので、処理がいつ始まって、いつ終わってもおかしくないと思います。 無限ループにdelayを入れたとしても、フリーズは回避されないかもしれませんね。 例えば、メインの処理だけが動き続けてiNum=20にしてしまい、サブのスレッドは全く動けず、iNum=10を期待して待ち続けて、その結果、無限ループに陥っているのかもしれません。 いずれにせよ、なぜフリーズするのか、状況を把握することは、必要でしょう。 組み直すのが一番早く、確実な解決方法だという結論になるかもしれませんが。
お礼
回答ありがとうございます、説明不足でした申し訳ありません。 処理が重くなるというより、処理に時間が掛かるの間違いです。 メインプログラムでもループしており、同じ用にdelay(1)を 入れようと思っています。この場合メインの処理が遅くなる為 SubAから処理が抜けるには、少なくても1000msec時間が 掛かると思います。 あくまで例ですので実際のプログラムは 5秒かもしれないし、10秒かも・・・出来るだけそれを避けたい ので思案中です。 // サブルーチンA(データ収集用) void SubA(){ for(iCnt=0;;iCnt++){ iBuf1[iCnt]=iCnt; // iBufにiCntの数を入れていく if(iNum == 10) break; // iNumに10が入ったら抜ける delay(1); // ←ここに追加 } // サブルーチンB void SubB(){ for(;;){ SubA(); iBuf2=iBuf1; if(iNum == 20) break; // iNumに20が入ったら抜ける delay(1); // ←ここに追加 } // メイン(別プログラム) Main(){ for(iCnt=0;;iCnt++){ if(iCnt == 1000)iNum = 10; if(iCnt == 2000)iNum = 20; delay(1); // ←ここに追加 } }
明確には書かれていませんがWindowsであって、問題の関数がCWnd派生クラスのメンバであれば、ループ中に以下の処理をすることによって、Windowsの操作が行える。 // ここから if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE)) { if (!GetMessage (&msg,NULL,0,0)) return; TranslateMessage(&msg); DispatchMessage(&msg); } // ここまで ただし問題の関数の実行は遅くなります。 詳しくは"メッセージループ"で検索するか、上記の関数名で検索してください。
お礼
回答ありがとうございます。 環境の説明不足でした。 QNX Software Systemsと言ったリアルタイムOS(UNIX系)を 使っており。 Wisdowsの操作は使えない状態です。
- digitalian
- ベストアンサー率29% (323/1104)
無限ループしたら、「ctrl + c」で強制終了させるとか。
お礼
回答ありがとうございます。 無限ループになってしまったらOS自体がフリーズしてしまう為 CTRL+Cも使えない状態になってしまっています。
- D-Matsu
- ベストアンサー率45% (1080/2394)
アプリ自身の優先度を下げれば、ビジーループ中でも他のアプリを阻害することはなくなります。 優先度が落ちるのでアプリの実行時間もそれだけ長くはなりますが。 もちろん最良なのは、言うまでもないとは思いますがそんな作りを根本から見直すことです。 どうやらマルチスレッドプログラムのようですから、スレッド待ち合わせ機構を使うとか。
お礼
回答ありがとうございます、アプリの優先順位を下げる方法は 以前おこなってみましたが、それでもPCがフリーズする現象に なってしまっていました。 どのプログラムよりも優先順位を 下げても同じ状態でした。 >もちろん最良なのは、言うまでもないとは思いますがそんな作りを >根本から見直すことです。 確かに根本的に作り直すのが望ましいのですが、低予算となると 現状大改造が出来ないのが現状です。社内で作成するプログラムでは スレッド待ち合わせ機構を使用しているのですが、他会社が 投げ捨てたソフトを改造するような状態ですのでどうしても 作り直しがつらい状況にあります。 出来るだけ最小限の包帯で 対応って感じです。
- hidebun
- ベストアンサー率50% (92/181)
ループ回数でbreakするとか、clock()で一定時間経過したら抜けるなど、 いくつか方法はあると思いますが、普通は、無限ループが発生させないようにすることに注力します。 なぜ無限ループが必要なのか、どういう処理を行いたいのかを補足してもらえると回答がつきやすいと思います。
お礼
回答ありがとうございます。 大まかな状態なのですが下記のような状態です。 ----------------------------------------------------- // サブルーチンA(データ収集用) void SubA(){ for(iCnt=0;;iCnt++){ iBuf1[iCnt]=iCnt; // iBufにiCntの数を入れていく if(iNum == 10) break; // iNumに10が入ったら抜ける } // サブルーチンB void SubB(){ for(;;){ SubA(); iBuf2=iBuf1; if(iNum == 20) break; // iNumに20が入ったら抜ける } // メイン(別プログラム) Main(){ for(iCnt=0;;iCnt++){ if(iCnt == 1000)iNum = 10; if(iCnt == 2000)iNum = 20; } } あくまで例ですが、このような感じでfor文やWhile文が 入り組んだ状態になっており、どこでフリーズしたんだろう? それを直すにはdelayを入れるのが手っ取り早いかな。 と言う次第であります。
お礼
回答ありがとうございます。 新規で開発する場合は、メッセージキュー(プロセス間通信)など を使用して、同期など取っているのですが、今回は予算も少なく、 他会社が捨てたプログラムの修正ですので、どうしても大幅な改造が 出来ない状態です。 根本的な所からソフトを作りたい所ですが、現状のソフトが フリーズする現象だけでも直す依頼ですので、つらい所が あります。 今後のプログラムを作成する上で色々と参考にさせて いただきます、ありがとうございました。