一个更好的Unix并行处理?

unix find(1)实用程序是非常有用的,允许我对许多匹配某些规范的文件执行操作,例如

 find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \; 

以上可能会在特定目录中的每个XML文件上运行脚本或工具。

假设我的脚本/程序需要很多CPU时间,而且我有8个处理器。 一次处理多达8个文件将是很好的。

GNU make允许使用-j标志进行并行作业处理,但find似乎没有这种function。 有没有一个替代的通用工作调度方法来解决这个问题?

xargs-P选项(进程数)。 假设我想压缩4-cpu机器目录中的所有日志文件:

 find . -name '*.log' -mtime +3 -print0 | xargs -0 -P 4 bzip2 

你也可以用-n <number>来表示每个进程的最大工作单元数。 所以说我有2500个文件,我说:

 find . -name '*.log' -mtime +3 -print0 | xargs -0 -n 500 -P 4 bzip2 

这会启动4个bzip2进程,每个进程有500个文件,然后当第一个完成时,会启动最后的500个文件。

不知道为什么以前的答案使用xargs make ,你有两个并行引擎!

GNU并行也可以提供帮助。

 find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {} 

请注意,如果没有-j8参数,则parallel默认为您计算机上的核心数量:-)

无需“修复” find – 利用自己来处理并行性。

让你的进程创build一个日志文件或其他输出文件,然后使用如下的Makefile:

 .SUFFIXES: .xml .out .xml.out: java -jar ProcessFile.jar $< 1> $@ 

并由此调用:

 find /dump -type f -name '*.xml' | sed -e 's/\.xml$/.out/' | xargs make -j8 

更好的是,如果确保在成功完成Java进程时才创build输出文件,则可以利用make的依赖性处理来确保下一次只有未处理的文件完成。

Find有一个可以直接使用“+”符号的并行选项; 不需要xargs。 把它和grep结合起来,就可以快速的通过你的树来寻找火柴。 例如,如果我正在寻找包含string“foo”的源代码目录中的所有文件,我可以调用
find sources -type f -exec grep -H foo {} +