我有一个计算时间很长的程序。我需要用不同的论据来称呼它。我想在有很多处理器的服务器上运行它们,所以我想并行启动它们以节省时间。(一个程序实例只使用一个处理器)
我已经尽力写了一个bash脚本,如下所示:

#!/bin/bash

# set maximal number of parallel jobs
MAXPAR=5
#  fill the PID array with nonsense pid numbers
for (( PAR=1; PAR<=MAXPAR; PAR++ ))
do
   PID[$PAR]=-18
done


# loop over the arguments
for ARG in 50 60 70 90
do
   # endless loop that checks, if one of the parallel jobs has finished
   while true
   do
      # check if PID[PAR] is still running, suppress error output of kill
      if ! kill -0 ${PID[PAR]} 2> /dev/null
      then
         # if PID[PAR] is not running, the next job
         # can run as parellel job number PAR
         break
      fi

      # if it is still running, check the next parallel job
      if [ $PAR -eq $MAXPAR ]
      then
         PAR=1
      else
         PAR=$[$PAR+1]
      fi

      # but sleep 10 seconds before going on
      sleep 10
   done

   # call to the actual program (here sleep for example)
   #./complicated_program $ARG &
   sleep $ARG &

   # get the pid of the process we just started and save it as PID[PAR]
   PID[$PAR]=$!

   # give some output, so we know where we are
   echo ARG=$ARG, par=$PAR, pid=${PID[PAR]}
done

现在,这个剧本行了,但我不太喜欢。
有没有更好的方法来处理开头?(设置PID[*]=-18在我看来是错误的)
如果没有丑陋的无限循环和几秒钟的睡眠,我该如何等待第一个任务完成呢?我知道这里有,但我不知道怎么用。
如果您对如何改进风格和简洁性有任何意见,我将不胜感激。

最佳答案

我有一个更复杂的代码,或多或少,做同样的事情。
你需要考虑的事情:
用户是否需要批准生成新线程
用户是否需要批准终止旧线程
线程是自行终止还是需要终止
用户是否希望脚本连续运行,只要它具有MaPAL线程
如果是,用户是否需要一个转义序列来停止进一步的繁殖?
下面是一些代码:

    spawn()                              #function that spawns a thread
    {                                    #usage: spawn 1 ls -l
        i=$1                             #save the thread index
        shift 1                          #shift arguments to the left
        [ ${thread[$i]} -ne 0 ] &&       #if the thread is not already running
        [ ${#thread[@]} -lt $threads] && #and if we didn't reach maximum number of threads,
        $@ &                             #run the thread in the background, with all the arguments
        thread[$1]=$!                    #associate thread id with thread index
    }

    terminate()                          #function that terminates threads
    {                                    #usage: terminate 1
        [ your condition ] &&            #if your condition is met,
        kill {thread[$1]} &&             #kill the thread and if so,
        thread[$1]=0                     #mark the thread as terminated
    }

现在,剩下的代码取决于您的需要(需要考虑的事情),所以您要么循环输入参数并调用spawn,然后在一段时间后循环线程索引和调用terminate。或者,如果线程自行结束,则循环输入参数并调用spawn和terminate,但终止的条件是:
[ ps -aux 2>/dev/null | grep " ${thread[$i]} " &>/dev/null ]
#look for thread id in process list (note spaces around id)

或者,一些类似的东西,你就明白了。

关于linux - 通过bash以不同的参数并行启动同一程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31145636/

10-12 19:11