我有一个计算时间很长的程序。我需要用不同的论据来称呼它。我想在有很多处理器的服务器上运行它们,所以我想并行启动它们以节省时间。(一个程序实例只使用一个处理器)
我已经尽力写了一个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/