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 & 

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

task1.sh:

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

task2.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 

一些检查目录是否为空的方法可以在这里find,不知道要用哪个;

:有没有更好的方法来实现这个?

PS可能的状态报告方法:

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

这正是gnu parallel所devise的,所以我强烈build议你使用它。 特别是把它看作是一个信号量 :

 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 

也许在这个变化呢?

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

你有什么特别的理由不使用像GNU并行 ? 如果你必须使用bash,那么考虑类似于这个博客文章中描述的方法(等待和命名pipe道在这里是有帮助的)。

“等待”等待所有后台作业完成。 样品:

睡30,睡40,睡120,等等

等待所有的命令完成,例如至less120秒。

希望这可以帮助。

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

所以我使用群体来实现一个,这就是所谓的信号量 。