shell 脚本:并行运行一批 N 条命令,等待所有命令完成后,再运行下 N 条

shell 脚本:并行运行一批 N 条命令,等待所有命令完成后,再运行下 N 条

任务:运行由 3-5 个命令组成的块(并行/后台)。示例块:

dd if=/dev/urandom of=/mnt/1/x bs=1024 count=1024000000 &
dd if=/dev/urandom of=/mnt/2/x bs=1024 count=1024000000 &
dd if=/dev/urandom of=/mnt/3/x bs=1024 count=1024000000 &

完成后,下一个块应该运行。我想,这可以通过锁定文件来完成:

任务1.sh:

real_task1 real_param1 ; rm /var/lock/myscript/task1.lock

任务2.sh:

real_task2 real_param1 ; rm /var/lock/myscript/task2.lock

...

taskgen.sh:

# loop
 # while directory isn't empty - wait...
 gen_tasks.pl # build task files from some queue
 for i in 1 2 3; do touch /var/lock/myscript/task$i.lock ; done
 ./task1.sh &
 ./task2.sh &
 ./task3.sh &
 # if task1.sh doesn't exits then exit, else loop waits for files to be deleted

有多种方法可以检查目录是否为空这里,不知道使用哪一个;

问题:有没有更好的方法来实现这一点?

PS 可能的状态报告方法:

 command && report_good_state.sh taskid ;  report_state_done.sh taskid; rm /var/lock/myscript/taskN.lock

答案1

这正是gnu并行是专为此目的而设计的,因此我强烈建议您使用它。特别是,看看运行它作为信号量

for i in {1..4}
do
  echo running $i
  sem -j3 df dd if=/dev/urandom of=/mnt/$i/x bs=1024 count=1024000000 ";" echo done
done
# sem --wait waits until all jobs are done.
sem --wait

答案2

也许对此有一些变化?

while true
do
  ./task1.sh&
  pid1=$!
  ./task2.sh&
  pid2=$!
  ./task3.sh&
  pid3=$!
  wait $pid1
  wait $pid2
  wait $pid3
done

答案3

你有什么特别的理由不使用类似的东西吗GNU并行? 如果必须使用 bash,请考虑以下方法这篇博文(等待和命名管道在这里很有帮助)。

答案4

我们尝试使用GNU sem 实用程序,如上文 Phil Hollenback 所述,但发现它太重了(300 多个实例使机器瘫痪)。我四处寻找类似的工具来实现轻量级计数信号量,但找不到合适的。

所以我自己用 flock 实现了一个,它叫信号灯

相关内容