等待bash中的作业,允许一次有限的并行作业,然后让所有人完成继续管道的其余部分

时间:2011-07-06 20:50:40

标签: bash

我正在运行GNU bash,版本3.2.39(1)-release(x86_64-pc-linux-gnu)。 我有一个特定的问题,关于等待在子shell中运行的作业,基于我想要允许的最大并行进程数,然后在管道中执行下一步之前等待剩余的子shell作业完成(如果我在这里有正确的意义)..

基本上,我的伪代码如下所示:

    MAX_PROCS=3
    for (( k = 0 ; $k < $kmerlen ; k += 1 ))
    do
    (
     ### Running a perl script here for each k (this script is a memory hog)...
    )&
    while [ $(ps -e | grep 'perlScriptAbove' | grep -v grep | wc -l) -gt ${MAX_PROCS} ] ; 
    do
       wait
    done

    done

    ###wait <- works fine without this wait, but I need all kmerlen jobs to finish first to proceed to the next part of the pipeline
    ## Run the rest of the pipeline...

while循环中的第一个wait语句可以很好地生成3个作业,但是当我使用下一个wait语句时,该属性会丢失,并且生成的子shell数量等于我的kmerlen

如果以前已经回答过,我很抱歉,但我似乎找不到。

非常感谢。

3 个答案:

答案 0 :(得分:5)

简单地调用wait应该等待所有 shell执行的后台作业,看起来这正是你需要的。

即。你的代码应该是这样的:

while (not all jobs spawned) # i.e. you want to do 40 jobs
  spawn as much jobs as you need in parallel (i.e. 4 jobs)
  wait

答案 1 :(得分:3)

GNU Parallel是为这种任务而制作的。并行gzip所有txt文件并将它们组合成一个大的.gz文件:

parallel gzip -c ::: *.txt > out.gz

观看介绍视频以了解详情:http://www.youtube.com/watch?v=OpaiGYxkSuQ

答案 2 :(得分:2)

不完全是bash,但确实按照你的要求行事: parallel-jobs是我做的perl程序。您指定一个“作业”文件,其中每一行是一个作业(一个bash一行),以及要并行执行的最大作业数,它将保持许多作业,直到所有作业都完成。

它适用于perl的标准安装(无需额外的模块)。您可能还想查看gnu parallel,这非常相似。