2

バックグラウンド

ロジックコントローラーからデータをキャプチャするために、端末エミュレーターとしてscreenを使用し、 KeySpanUSA-19HSUSBシリアルアダプターを介してMacBookを接続しています。次のbashスクリプトを作成したので、talk2controller <filename>filenameデータファイルの名前です。

#!/bin/bash
if [ -z "$1" ]; then
    echo Please provide the filename to save the logfile
    exit
fi
LOGFILE=$1
echo "logfile $1" > screenrc        # Set the logfile filename
echo "logfile flush 1" >> screenrc  # Wait 1 sec before flushing buffer to filesystem
screen -L -c screenrc /dev/tty.KeySerial1 19200

ログファイルのファイル名を変更し、ログファイルバッファをファイルシステムにフラッシュする前に待機するためにデフォルトの10秒から1秒に変更しました。それらのコマンドをに保存しますscreenrc。次に、次のコマンドで画面を呼び出します。

  1. -L—ロギングが有効
  2. -c screenrc—デフォルトの構成ファイルをオーバーライドします
  3. /dev/tty.KeySerial1 19200—19200のボーレートを使用してシリアルポートと通信します

私が記録する各テストには約3〜6分かかり、速度、加速度、および位置の情報が含まれています。加速率からテストが有効だったことがわかります。現在、テストが終了するまで待ってから、Python matplotlibスクリプトを実行して速度、加速度、位置をプロットし、テストが有効かどうかを確認してから、次のテストに進みます。

時間を節約するために、データがまだキャプチャされている間に、テストの約半分でデータをプロットしたいと思います。

質問

私の考えでは、より多くのデータがまだキャプチャされている間にデータをプロットするための2つのオプションがあります。

  • オプション1: screenを使用してデータをログに記録し、Pythonmatplotlibスクリプトに部分的なログファイルを読み取らせます。
    • 質問1:画面がまだデータを書き込んでいる間にPythonスクリプトがログファイルを読み取る場合、どのような懸念がありますか?
  • オプション2: screenの使用からpySerialの使用に切り替えます。ただし、テスト中にデータをプロットすることは、テスト中にデータをキャプチャすることよりも優先度が低くなります。コードのプロット部分で例外が発生し、データロギングが失敗することは許されません。これがscreenの優れている点です。データをダンプするだけで、他のことは何もしません。
    • 質問2: pySerialに切り替える場合、コードのプロット部分がデータキャプチャコードに影響を与えない可能性を減らすために2つのスレッドを実行できますか?これは私に何かを買いますか?

質問3:私が考えていなかったより良いオプションはありますか?

4

3 に答える 3

3

オプション 1 と 2 の両方が機能しますが、これにはスレッドを使用しないでください。ロックの問題、グラフ作成スレッドでの例外により、いずれにせよプログラム全体 (ロギング スレッドを含む) が強制終了されます。他の誰かが述べたように、これには 2 つの別々のプロセスを使用しても問題ありません。 screenPython で手作業でコードを書く場合と同様に、この目的のためのツールの選択は少し奇妙です。talk2controller スクリプトを次の簡単なスクリプトに書き直します。

stty -F /dev/tty.KeySerial1 19200 raw
cat </dev/tty.KeySerial1 >logfile

>>logfile(スクリプトを最初から書き直すのではなく、スクリプトを実行するたびにファイルに追加する場合にも使用できます。)

もう 1 つの問題は、他の誰かがファイルに書き込んでいる限り、プログラムがそのファイルから読み取っても大丈夫かどうかということです。この質問のより具体的なバージョンは、次のとおりです。ログを読み込もうとしたときに、ログの行が半分書き込まれている場合はどうなりますか?

答えは次のとおりです。これを行うことは許可されていますが、そのとおりです。行を読んだときに行が半分書かれていないことを保証することはできません。cat(独自のorの置換を作成する場合、orの代わりにscreen常にファイルに書き込むことで、実際にこの保証を行うことができます。)os.read()sys.stdout.write()print

ただし、とにかくその保証は必要ありません。ファイルを読むときに注意するだけで問題はありません。\n基本的に、不完全な行とは、改行文字で終わらない行のことです。したがって:

for line in open('logfile'):
    if not line.endswith('\n'): break
    ...handle valid line...

\n文字はログの各行で最後に書き込まれるものであるため、文字を読み取れば、それ以前のすべてが正しく書き込まれたことが確実にわかります\n

于 2010-09-17T00:26:32.857 に答える
1

オプション1は完全に実行可能だと思います。なぜなら、Pythonがログファイルを読み取り専用パイプに簡単に「テール」して、screen書き込み中に害を及ぼさないようにすることができるからです。ファイルを追跡している間、ログ ファイルで新しいログ イベントが検出されるたびに、指定されたアクションを実行できます。

興味があり、動作するコードを確認したい場合は、私の個人的なプロジェクトでこの機能を利用しています。プロジェクトはthrasher-logdropと呼ばれ、中身はlogdrop.pyです。基本的な流れは次のとおりです。

  • ファイルをテールしますdo_tail()
  • ログイベントを監視するtail_lines()
  • でイベントに対してアクションを実行しますhandle_line()
于 2010-09-14T18:24:49.780 に答える
1

オプション2が進むべき道だと思います。受信した入力の各バイトで何をするかを完全に制御できます。読み取り時にデータをディスクに書き込むだけの非常に単純な Python スクリプトを作成できます。プロット コードはfork()、最初の ing によって作成された完全に別のプロセスで実行できます。あるプロセスから別のプロセスへデータを取得するには、(a) 最初のプロセスで、socketpair()または他の IPC メカニズムに書き込むこともできます。または (b) 出力ファイル オブジェクトをライン バッファリングするように構成し (行全体が書き込まれるたびに明示的に同期するようにします)、2 番目のプロセスで新しいコンテンツを監視します。

screenオプション 1 の問題は、のバッファリング動作を制御できないことです。新しいコンテンツのログファイルを監視できますが、ロギング コードは、不完全な行と大量のデータの両方を一度に処理できるように準備する必要があります。screen正確なバッファリング動作によっては、プロセスが終了するまでデータがまったく表示されない場合もあります!

于 2010-09-14T18:56:07.377 に答える