How to run given function in Bash in parallel?

后端 未结 3 949
故里飘歌
故里飘歌 2021-01-30 14:00

There have been some similar questions, but my problem is not \"run several programs in parallel\" - which can be trivially done with parallel or xargs

3条回答
  •  借酒劲吻你
    2021-01-30 14:18

    Solution to run multi-line commands in parallel:

    for ...your_loop...; do
      if test "$(jobs | wc -l)" -ge 8; then
        wait -n
      fi
    
      {
        any bash commands here
      } &
    done
    wait
    

    In your case:

    for i in "${list[@]}"
    do
      for j in "${other[@]}"
      do
        if test "$(jobs | wc -l)" -ge 8; then
          wait -n
        fi
    
        {
          your
          multi-line
          commands
          here
        } &
      done
    done
    wait
    

    If there are 8 bash jobs already running, wait will wait for at least one job to complete. If/when there are less jobs, it starts new ones asynchronously.

    Benefits of this approach:

    1. It's very easy for multi-line commands. All your variables are automatically "captured" in scope, no need to pass them around as arguments
    2. It's relatively fast. Compare this, for example, to parallel (I'm quoting official man):

    parallel is slow at starting up - around 250 ms the first time and 150 ms after that. 3. Only needs bash to work.

    Downsides:

    1. There is a possibility that there were 8 jobs when we counted them, but less when we started waiting. (It happens if a jobs finishes in those milliseconds between the two commands.) This can make us wait with fewer jobs than required. However, it will resume when at least one job completes, or immediately if there are 0 jobs running (wait -n exits immediately in this case).
    2. If you already have some commands running asynchronously (&) within the same bash script, you'll have fewer worker processes in the loop.

提交回复
热议问题