Duc*_*uck 25 shell background-process parallelism
我在一个目录中有一堆 PNG 图像。我有一个名为 pngout 的应用程序,我运行它来压缩这些图像。这个应用程序是由我做的脚本调用的。问题是这个脚本一次执行一个,如下所示:
FILES=(./*.png)
for f in "${FILES[@]}"
do
echo "Processing $f file..."
# take action on each file. $f store current file name
./pngout -s0 $f R${f/\.\//}
done
Run Code Online (Sandbox Code Playgroud)
一次只处理一个文件,需要很多时间。运行此应用程序后,我看到 CPU 仅为 10%。所以我发现我可以将这些文件分成 4 个批次,将每个批次放在一个目录中并从四个终端窗口、四个进程中触发 4 个,所以我有四个脚本实例,同时处理这些图像和工作需要 1/4 的时间。
第二个问题是我浪费了时间分割图像和批处理并将脚本复制到四个目录,打开4个终端窗口,bla bla ...
如何用一个脚本做到这一点,而不必分割任何东西?
我的意思是两件事:首先,我如何从 bash 脚本启动一个进程到后台?(只是在最后加&?) 第二:如何在发送第四个任务后停止向后台发送任务并让脚本等待任务结束?我的意思是,只是在一个任务结束时向后台发送一个新任务,始终保持 4 个任务并行?如果我不这样做,循环将向后台发送无数个任务,CPU 将阻塞。
jw0*_*013 34
如果你有一个xargs支持并行执行的副本-P,你可以简单地做
printf '%s\0' *.png | xargs -0 -I {} -P 4 ./pngout -s0 {} R{}
Run Code Online (Sandbox Code Playgroud)
对于其他想法,Wooledge Bash wiki在 Process Management 文章中有一个部分准确描述了您想要什么。
除了已经提出的解决方案之外,您还可以创建一个 makefile 来描述如何从未压缩的文件中制作压缩文件,并用于make -j 4并行运行 4 个作业。问题是您需要以不同的方式命名压缩文件和未压缩文件,或者将它们存储在不同的目录中,否则将无法编写合理的 make 规则。
如果你安装了 GNU Parallel http://www.gnu.org/software/parallel/你可以这样做:
parallel ./pngout -s0 {} R{} ::: *.png
Run Code Online (Sandbox Code Playgroud)
您可以简单地通过以下方式安装 GNU Parallel:
wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem
Run Code Online (Sandbox Code Playgroud)
观看 GNU Parallel 的介绍视频以了解更多信息:https : //www.youtube.com/playlist?list=PL284C9FF2488BC6D1
回答你的两个问题:
wait命令,您可以要求 shell 等待后台中的所有进程完成,然后再继续进行。这是修改后的脚本,j用于跟踪后台进程的数量。当NB_CONCURRENT_PROCESSES到达,该脚本将重置j为0,并恢复它的执行之前等待所有的后台进程完成。
files=(./*.png)
nb_concurrent_processes=4
j=0
for f in "${files[@]}"
do
echo "Processing $f file..."
# take action on each file. $f store current file name
./pngout -s0 "$f" R"${f/\.\//}" &
((++j == nb_concurrent_processes)) && { j=0; wait; }
done
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17160 次 |
| 最近记录: |