在bash中启动n个子进程,然后等待一切完成



我想测试几个ffmpeg设置,并将多个命令作为"子进程"运行。不过,我不想一次启动超过4个进程。做这件事的好方法是什么?也许是在bg中运行进程之前捕获进程id,然后等待它们不再在进程列表中?还是xargs?

这是没有"排队"的脚本:

#!/bin/bash
for crf in 10 15 20 23 25 30 35 ; do
for vid_preset in medium slow veryslow; do
ffmpeg -r 25 -i pics/pic_%04d.png -vcodec libx264 -crf $crf -vpre $vid_preset anim_crf$crf_$vid_preset.mp4
done
done

一个非常简单的方法是只在后台运行每个ffmpeg进程,然后等待它们完成,然后再执行crf的下一个值。

for crf in 10 15 20 23 25 30 35 ; do
for vid_preset in medium slow veryslow; do
ffmpeg -r 25 -i pics/pic_%04d.png -vcodec libx264 
-crf $crf -vpre $vid_preset anim_crf${crf}_${vid_preset}.mp4 &
done
wait
done

如果安装了parallel,则可以使用它以繁忙的方式运行所有21个进程。

# Run 4 jobs at a time, starting a new job whenever one completes.
parallel -j 4 ffmpeg -r 25 -i pics/pic_%04d.png 
-vcode libx264 -crf {1} -vpre {2} 
anim_crf{1}_{2}.mp4 ::: 10 15 20 23 25 30 35 ::: medium slow veryslow

{1}被来自第一输入源(在第一:::之后)的选择所代替,{2}被来自第二输入源的选择所取代。一个例子解释得更简单:

$ parallel echo {1} {2} ::: a b c :: 1 2
a 2
a 1
b 1
b 2
c 1
c 2

bash4.3或更高版本(当引入wait -n时)中的混乱方法:

max_jobs=4
running=()
for c in 10 15 20 23 25 30 35; do
for v in medium slow veryslow; do
ffmpg ... &
running+=($!)
# If we're at capacity, wait for a job to complete
if (( ${#running[@]} == $max_jobs )); then
wait -n
# Any where from 0 to max_jobs - 1 could still be running
running=( $(jobs -p) )
fi
done
done

相关内容

  • 没有找到相关文章

最新更新