• ベストアンサー

1分おきにファイルに保存したい

Vine Linux 3.1のgccを使用しています。 早速ですが質問です。 シリアルポートへ不定期(数秒~数分間隔 バイナリデータ)に入ってくるデータを そのつど解析し分類別にカウント。 その結果を1分おきに ファイルへ保存したいと思っています。 シリアルポート周りやデータ処理周りは何とか 作れたのですが1分おきに・・・のところで つまずいています。 alarm(60);でシグナルを発生させ、 sigaction(SIGALRM・・・を使用し シグナルを補足、シグナルハンドラを処理後 select()(←シリアルポートのread()を待っている) のところで Interrupted system call が発生してしまいます。 CPU負荷をかけたくないので無限ループで時間を 毎回チェック・・・等は可能な限り避けたいと 思っています。 上記方法に限らず、何か良い方法とかありましたら 是非、ご教授ください。 どうぞよろしくお願いいたします。

  • qc024
  • お礼率90% (10/11)

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

  • ベストアンサー
回答No.2

ブロッキングモードでselectしてますか? あと、sleep()じゃなくてわざわざalrm()を使うのは何故でしょうか? あと、複数のシリアルポートをポーリングするんじゃなければ、select()使わずに、ブロッキングモードでオープンしてread()だけですむ気がするんですけど。

qc024
質問者

お礼

補足するに書きたかったのですが、クリックできない ので、お礼を投稿するに書かせていただきました・・・ >ブロッキングモードでselectしてますか? ソースを見てみましたが、いまいち理解できません できたらもう少し詳しくご説明願えないでしょうか? read()は不要なループを避けるため、ブロッキング モードになっています。 これがいけないのでしょうか? ちなみにsigaction()関連は以下のとおりです alarm(60); struct sigaction act; act.sa_handler = warikomi; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, 0); どうぞよろしくお願いいたします

qc024
質問者

補足

ご回答ありがとうございます >ブロッキングモードでselectしてますか? ソースを確認してみます >あと、sleep()じゃなくてわざわざalrm()を使うのは何故でしょうか? 受信するデータが連続して大量に来ることがあるのでalrm()を使用しています。 sleep()を使用するとバッファ(4096byte)からあふれて取りこぼしが発生してしまいました。 >select()使わずに、ブロッキングモードでオープンしてread()だけですむ気がするんですけど。 勉強不足です。早速調べてみます。

その他の回答 (3)

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

以下の方法ではどうでしょうか。 1.selectの呼び出しをタイムアウト時間指定(例えば1秒)で行う。 2.selectのタイムアウトの時、1に戻るが、前回に書いた時間から1分経過していれば、ファイルへ書き込む。 3.データ受信完了後、1に戻るが、前回に書いた時間から1分経過していれば、ファイルへ書き込む。 上記を繰り返します。少なくとも、selectの中でsleepするのでCPUは、消費しません。

qc024
質問者

お礼

ご回答ありがとうございます。 ループの回数を可能な限り減らそうと思い、 現時点ではread()をブロックモードにしています。 うまく解決できないようであれば、この方法でやりたいと思います。

  • neo_ap1
  • ベストアンサー率26% (105/395)
回答No.3

あ、すみません。 シリアルポート監視は不定期ですね・・・。 見落としておりました。 cronでやるなら仰るとおり別々ですかね。 カウントはメモリ上に展開するか、 一時ファイルに出力するか・・・でしょうか。 う~ん、いまいちですね。 お役に立てず、失礼いたしました・・・。

qc024
質問者

お礼

>お役に立てず、失礼いたしました・・・。 いえいえ、そんなことありません。 今回に限らず、cronでの発想は私にはありませんでした。 今後機会があったら是非使ってみたいと思います。 ありがとうございました。

  • neo_ap1
  • ベストアンサー率26% (105/395)
回答No.1

ループしない単発のプログラムを作成し、 cronデーモンで指定分毎に起動すると言うのはどうでしょうか?

qc024
質問者

補足

ご回答ありがとうございます。 >cronデーモンで指定分毎に起動すると言うのはどうでしょうか? シリアルポート関連を専門に行うプログラムと、 cronデーモンで起動するファイル保存専用 プログラムに分けて・・・と言う解釈でよろしい でしょうか? この場合、カウントしているデータを取得するには どのような方法があるのでしょうか? もしよろしければ、ご教授ください。 よろしくお願いいたします。

関連するQ&A

  • Arduino シリアル通信でのバイナリ受信

    詳しい方教えてください。 送信元のPCから、受信側のArduinoへ、シリアル通信によってバイナリデータを送ることで、Arduino側でのサーボモータのシリアル駆動を試みています。 PC側からのバイナリデータ送信はVB.NET側で作成済みで、USB-TTLコンバータ(FTDI Basic Breakout 5V)を使ってのサーボモータのシリアル駆動は問題ありません。 (http://micono.cocolog-nifty.com/blog/2011/04/arduino11-17d5.html と同じ処理と思ってください。) 同様な処理を、PC-Arduinoで駆動させようと思っていますが、 void loop() { int c; if (Serial.available() > 0){ c = Serial.read(); ・・・・ こちらでは、Cの値がint型の為かうまくいきません。(キャストも試しましたが・・) そもそも1バイトデータの受信Serial.read()が、int型(2バイト)なのか判りません。 方法はありますでしょうか。

  • RubyでバイナリデータをIOストリームにする方法

    Rubyで、バイナリデータをIOストリームに変換する方法を探しています。 Railsで、データベースに格納された アップロード済のPDFファイル(バイナリデータ)を、 PDF::readで読み込んで処理したいのですが、 PDF::readは、ファイルパスかIOストリームしか受け付けてくれないようなのです。 よろしくお願いします。

  • InputStreamクラスの仕様

    InputStreamクラスのreadメソッドを使用しています。 InputStreamには1MBのデータがバイナリで格納されており、2KBずつ byte配列にreadメソッドを使用して格納する処理を行っています。 処理自体は問題なく終了するのですが、readメソッドを使用して8KBほど 読み込んだ後、決まってパフォーマンスが悪くなり100Bしか読み取れず、 また8KB読み込んで100B読み込むといった処理になってしまいます・・・。 これはInputStreamのreadクラスの仕様なのでしょうか?それとも何か対策があるのでしょうか? ちなみにInputStreamクラスの元ねたはHTMLにてmultipart/form-dataを使用して アップロードしたファイルデータが格納されています。

    • ベストアンサー
    • Java
  • オブジェクトのバイナリ保存

    アプリケーションで扱うデータの保存方法を模索中なのですが iniファイルやxmlファイルのような形式ですと、テキストファイルで変更することができるので BinaryFormatterを使用してバイナリで保存しようと考えています。 そこで、iniファイルやxmlのようにテキストファイルで保存する場合と BinaryFormatterを用いてバイナリ形式で保存する場合を比較したとき、 どちらの方が処理的に有利(処理が早い、軽いなど)とかあるのでしょうか? また、何度も何度もファイルへの書き込み処理が発生する場合、 どちらの方が処理的に有利(処理が早い、軽いなど)とかあるのでしょうか? 以上、よろしくお願いします。 環境 .NET FrameWork 2.0

  • VBによるシリアルポート制御

    VB6でシリアルポートからデータを取り込むプログラムを作っています。 データは、バイナリモードで、合計26バイトあります。 これが、20ms間隔で送られてくるデータは、うまく取れたのですが、データを送る間隔を5msにしたところ、うまく受信できないようで、データが表示されなくなってしまいました。 ちなみに20ms間隔の時のシリアルポートのスピード設定が19200bpsで、5ms間隔の時には、115200bpsに変更しています。 VBで115200bpsのポート制御は難しいのでしょうか? それとも、小生のプログラムに問題があるのでしょうか?

  • SIGIOについて

    SIGIOの解説をみると「I/Oが使用可能になった」との記述がありますが これは例えばシリアルポートに当てはめると受信完了と送信可能の場合に発行 されるシグナルなのでしょうか?

  • バイナリデータの書き方が分かりません・・。

    シリアルポートでバイナリデータを送信したいのですが、バイナリをどう書けがいいのか分りません。 送りたいコードは16進数で02 00 02 00です。 以下のソースの"123"の部分を書き換えるのだと思うのですが、どう書けば良いのでしょうか? よろしくお願いします。 char* wbuf; DWORD wbyte; lstrcpy(wbuf,"123"); WriteFile(hCom,wbuf,lstrlen(wbuf),&wbyte,&old

  • snortでパケット内容(ヘッダ&データ)のテキスト形式でのフル出力の仕方は?

    こんにちは。 RedHat9 | vine3.1 としています。 RedHat9のディレクトリをvine3.1にてNFSマウントする時に RedHat9のportmapからvine3.1に与えられるランダムのポートが何番なのか RedHat9のsnortで知りたく思っています。 tcpdumpはバイナリでしか出力されなくて、snortはテキスト形式でも出力してくるらしいのです。 (パイプ処理やテキストファイルにリダイレクトしたいのでsnortの方がいいかなと思います) snort 2.0.4 をRedHat9で使用しています。 [root@rh9]# snort -A cmd としたのですが(snort2.0.1についての参考書にて) 「ERROR: Unknown commnd line alert options:cmd Fatal Error,Quitting...」 となっています。 どうすれば、テキスト形式にフル出力させれるのでしょうか?

  • 仮想COMポートからの読み込みがうまくいきません

    USB接続の仮想COMポート接続デバイス相手のプログラムをVB6.0で作成中です。 WindowsXP上では問題なく送受信できるのですが、Windows2000上では 問題が発生します。512byteのバイナリデータを受信したいのですが、途中でデバイス側の応答が止まってしまいます。 MSCOMMを使用していたので、それが良くないのかと思い、他のもの(CommOcx)を使用してみましたが結果は変わりませんでした。 Windows2000の場合には、なにか特別な処理が必要なのでしょうか?

  • ブロッキングI/Oについて

    シリアルポートとGPIOポートを両方使用したプログラムを作成しました。read関数を使用した部分でブロッキングI/Oが原因となりGPIOポートが利用できなくなるという問題が起きました。 この問題自体はノンブロッキングI/Oの設定を行うことで解決できたのですが、以下の疑問が残りました。 ・なぜI/O処理をブロックする必要があるのか ・ブロッキングI/OとノンブロッキングI/Oはどのように使い分けるのか ・ブロッキングI/Oという機能は何故出来たのか I/Oポートの制限を行わない方がプログラムを作成しやすいと思うのですが、なぜread関数などは初期状態がブロッキングする状態になっているのでしょう。