后台并行执行

wwj*_*oze 2 background-process parallelism

我有一个带有./pgm一些参数的程序(比如-a file1 -b val),它需要 2 秒来执行。我想使用我机器上的所有处理器在所有输入文件上并行运行这个程序(大约 1000 个)。我现在要做的是把所有的命令

./pgm -a file1 -b 12 > out1.txt &
./pgm -a file2 -b 14 > out2.txt &
./pgm -a file3 -b 16 > out3.txt &
./pgm -a file4 -b 18 > out4.txt &
...
Run Code Online (Sandbox Code Playgroud)

在一个文件中,并执行这个文件。我以为这会使用所有可用的处理器,但并行执行的数量非常有限。

我怎样才能做到这一点?请注意,parallel命令不是一个选项。

Sté*_*las 5

使用 GNU xargs

seq 1000 | xargs -P4 -n1  sh -c 'exec ./pgm -a "file$1" -b 12 > "out.$1"' sh &
Run Code Online (Sandbox Code Playgroud)

最多可./pgm并行运行 4秒。

否则,与pdksh/ mksh/ oksh

trap : CHLD
n=0
for f in file*; do
  jobs=$(jobs | wc -l)
  if (($jobs < 4)); then
    ./pgm "$f" > out.$((++n)) &
  else
    wait
  fi
done
trap - CHLD
wait
Run Code Online (Sandbox Code Playgroud)

信号处理的细节因一个外壳而异。该技巧适用于pdksh及其衍生物,但不适用于我尝试过的任何其他 shell。您需要一个可以捕获 SIGCHLD(排除bash)的外壳,在其中立即执行 SIGCHLD 处理程序(在 a 期间不被阻塞wait)(排除ash, yash),其中 SIGCHLD 处理中断wait(排除ksh93zsh)。

在 以外的 shell 中bash,您还可以查看在 SIGCHLD 处理程序中启动作业的方法。