我正在使用这样的东西:
find folder/ | xargs -n1 -P10 ./logger.py > collab
Inside 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}
如何预防/纠正此事?
答案 0 :(得分:2)
一般来说,有些问题会导致很难保证这种情况不会发生,而不会深入研究多进程锁定。但是,您通常可以减少很多问题。
最常见的原因是I / O缓冲,在Python或libc中。例如,它可以缓冲16k的输出,然后立即写入整个块。你写完之后可以通过刷新标准来减少它,但那很尴尬。从理论上讲,你应该能够将-u
传递给Python以禁用stdout缓冲,但是当我尝试它时它不起作用。有关更通用的解决方案,请参阅Sebastjan对Disable output buffering的回答(尽管可能有一种方法可以更直接地禁用输出缓冲)。
第二个问题是底层写入并不总是原子的。特别是,对管道的写入只是一个特定大小的原子(PIPE_BUF,通常是512字节);以上,不保证。这仅适用于管道(而不是文件),但同样的一般问题也适用:较小的写入更可能以原子方式发生。请参阅http://www.opengroup.org/onlinepubs/000095399/functions/write.html。
答案 1 :(得分:1)
复杂且技术上正确的解决方案是实现写入的互斥,但我认为这不是最理想的。
无论如何它并不好玩。如何管理xargs的输出(这样你得到了坚实的输出块,而不是被分解的输出流)然后以某种方式组合这些块?
答案 2 :(得分:1)
问题是xargs的输出混合在一起。 GNU Parallel用于解决该问题。默认情况下,它保证输出不会混合在一起。所以你可以这样做:
find folder/ | parallel ./logger.py > collab
这将为每个CPU运行一个logger.py。如果你想要10:
find folder/ | parallel -P10 ./logger.py > collab
观看introvideo以了解有关GNU Parallel http://www.youtube.com/watch?v=OpaiGYxkSuQ
的更多信息