私はデータロギングアプリを書いています、すべてのプログラムは次のように開始されます:
_./program > out.bin
_
データコレクターは定期的にstdout出力ファイルをプールし、データを読み取ります。
問題は、IOストリームがバッファリングされ、一部のプログラムが1バイト/秒のようにデータを出力する場合、データが実際に出力されるまでに多くの時間がかかることです(デフォルトの4kBバッファサイズでは最大4k秒)。洗い流された。
私の質問は、stdout/pipe/printfバッファを強制的に外部でフラッシュする方法、つまりfflush(stdout)
のような外部で呼び出す方法です。
パイプ内のバッファリングをオフにする のようなさまざまなサイトを読んだことがありますが、IOのパフォーマンスに大きな影響があるため、バッファを無効にすることはできません(測定)。
私は生産のための高性能ソリューションを探しています、そしてこれらの以下の条件は常に満たされます:
実行中のプログラムのソースにアクセスできますか?
任意の実行可能ファイルのフラッシュを強制することは、理論的には不可能ではありませんが、非常に困難です。コード内でfflush
関数とstdout
引数を見つけて、プログラムの実行を中断し、fflush
の呼び出しを手配してから、実行を続行する必要があります。プログラムが共有ライブラリを使用している場合は、少なくとも最初の部分が簡単になり、fflush
とstdout
が見つかりますが、それでも呼び出しをシミュレートする必要があります。また、不明なバイナリの場合、stdioを使用したのか、独自のバッファリングメカニズムを実装したのかを知ることはできません。出力ファイルのパスを知っていることは役に立ちません。
gdb
を使用してから、attach
コマンドを使用してプロセスにアタッチできます。たぶん、gdb
はfflush
関数を呼び出すことができます。
プログラムのソースがある場合は、バッファーをフラッシュするシグナルハンドラーを実装し、バッファーをフラッシュするときにシグナルを送信するだけです。
パイプを試すことができます。出力がパイプの場合、プログラムはバッファリングしない可能性があります。に変更します
./program | your_program > out.bin
プログラムは入力を受け入れ、それをバッファリングし、信号を受信するとバッファをフラッシュできます。それでもCPUオーバーヘッドは追加されますが、ディスクオーバーヘッドは追加されません。
gdb -p PID -batch -ex 'p fflush(stdout)'
他のデバッグやハッキングと同様に、YMMV。