mat*_*ath 11 bash zsh shell parallel-processing
我想处理很多文件,因为我这里有一堆内核,所以我想并行处理:
for i in *.myfiles; do do_something $i `derived_params $i` other_params; done
Run Code Online (Sandbox Code Playgroud)
我知道 Makefile解决方案,但我的命令需要 shell globbing 列表中的参数。我发现的是:
> function pwait() {
> while [ $(jobs -p | wc -l) -ge $1 ]; do
> sleep 1
> done
> }
>
Run Code Online (Sandbox Code Playgroud)
要使用它,只需将 & 放在作业和 pwait 调用之后,参数给出并行进程的数量:
> for i in *; do
> do_something $i &
> pwait 10
> done
Run Code Online (Sandbox Code Playgroud)
但这并不能很好地工作,例如,我尝试使用 for 循环转换许多文件但给我错误并留下未完成的作业。
我不敢相信这还没有完成,因为关于 zsh 邮件列表的讨论现在已经很老了。那么你知道更好的吗?
Gil*_*il' 15
makefile可以很好地解决您的问题。您可以在 shell 中对这种并行执行进行编程,但正如您所注意到的,这很难。make 的并行实现不仅会处理启动作业和检测它们的终止,还会处理负载平衡,这很棘手。
globbing 的要求不是障碍:有支持它的 make 实现。GNU make,它具有通配符扩展,例如$(wildcard *.c)和 shell 访问,例如$(shell mycommand)(在 GNU make 手册中查找函数以获取更多信息)。它是makeLinux上的默认设置,可用于大多数其他系统。这是一个 Makefile 框架,您可以根据自己的需要进行调整:
来源 = $(通配符 *.src)
全部:$(来源:.src=.tgt)
%.tgt: %.src
do_something $< $$(derived_params $<) >$@
运行类似make -j4并行执行四个作业,或make -j -l3将平均负载保持在 3 左右的操作。
小智 8
我不确定你的派生参数是什么样的。但是使用 GNU Parallel http://www.gnu.org/software/parallel/ 你可以这样做来为每个 CPU 核心运行一项工作:
find . | parallel -j+0 'a={}; name=${a##*/}; upper=$(echo "$name" | tr "[:lower:]" "[:upper:]");
echo "$name - $upper"'
Run Code Online (Sandbox Code Playgroud)
如果您想要派生的只是更改 .extension,那么 {.} 可能会很方便:
parallel -j+0 lame {} -o {.}.mp3 ::: *.wav
Run Code Online (Sandbox Code Playgroud)
在http://www.youtube.com/watch?v=OpaiGYxkSuQ 上观看 GNU Parallel 的介绍视频
使用 shell 的wait命令对您不起作用吗?
for i in *
do
do_something $i &
done
wait
Run Code Online (Sandbox Code Playgroud)
您的循环执行一个作业,然后等待它,然后执行下一个作业。如果上述方法对您不起作用,那么如果您pwait在done.
| 归档时间: |
|
| 查看次数: |
19999 次 |
| 最近记录: |