8

私はこのようなものを使用しています:

find folder/ | xargs -n1 -P10 ./logger.py > collab

内部logger.pyでは、再フォーマットされた行を出力してファイルを処理しています。したがって、コラボは次のようになります

{'filename' : 'file1', 'size' : 1000}
{'filename' : 'file1', 'size' : 1000}
{'filename' : 'file1', 'size' : 1000}
{'filename' : 'file1', 'size' : 1000}

代わりに、行がごちゃごちゃになっていることがあります。

{'filename' : 'file1', 'size' : 1000}
{'file
{'filename' : 'file1', 'size' : 1000}
name' : 'file1', 'size' : 1000}
{'filename' : 'file1', 'size' : 1000}

これを防ぐ/修正するにはどうすればよいですか?

4

3 に答える 3

2

一般に、マルチプロセスのロックを掘り下げることなく、これが起こらないことを保証することを非常に困難にする問題があります。ただし、通常は問題を大幅に減らすことができます。

これの最も一般的な原因は、Python または libc 内の I/O バッファリングです。たとえば、16k の出力をバッファリングしてから、ブロック全体を一度に書き込む場合があります。書き込み後に標準出力をフラッシュすることでそれを減らすことができますが、それは厄介です。-u理論的には、 Python に渡して stdout バッファリングを無効にできるはずですが、試してみるとうまくいきませんでした。より一般的な解決策については、出力バッファリングを無効にするに対する Sebastjan の回答を参照してください(おそらく、出力バッファリングをより直接的に無効にする方法があります)。

2 つ目の問題は、基になる書き込みが常にアトミックであるとは限らないことです。特に、パイプへの書き込みは、特定のサイズ (PIPE_BUF、通常は 512 バイト) まではアトミックです。それ以上は保証されません。これは厳密にはパイプ (ファイルではなく) にのみ適用されますが、同じ一般的な問題が適用されます。小さな書き込みはアトミックに発生する可能性が高くなります。http://www.opengroup.org/onlinepubs/000095399/functions/write.htmlを参照してください。

于 2011-02-16T22:40:20.603 に答える
1

問題は、xargs からの出力が混在していることです。GNU Parallel は、その問題を解決するために作られました。デフォルトでは、出力が混在しないことが保証されます。したがって、これを簡単に行うことができます:

find folder/ | parallel ./logger.py > collab

これにより、CPU ごとに 1 つの logger.py が実行されます。10 が必要な場合:

find folder/ | parallel -P10 ./logger.py > collab

GNU Parallel の詳細については、イントロビデオをご覧ください http://www.youtube.com/watch?v=OpaiGYxkSuQ

于 2011-02-17T13:53:16.393 に答える
1

複雑で技術的に正しい解決策は、書き込み用のミューテックスを実装することですが、それは最適ではないと思います。

そしてとにかく楽しくない。xargs からの出力をパイプ処理して (分割された出力のストリームではなく、しっかりした出力のチャンクを取得する方法)、これらのチャンクを何らかの方法で結合するのはどうですか?

于 2011-02-16T22:38:46.357 に答える