KSH:约束一次可以运行的线程数

时间:2011-12-01 15:34:45

标签: linux bash concurrency ksh sh

我有一个循环脚本,每次迭代调用一个在后面运行的线程,如下所示

xn_run_process.sh

...
for each in `ls ${INPUT_DIR}/MDX*.txt`
do
      java -Xms256m -Xmx1024m -cp ${CLASSPATH} com.wf.xn.etcc.Main -config=${CONFIG_FILE}
      ...
      for SCALE_PDF in `ls ${PROCESS_DIR}/*.pdf`
      do
          OUTPUT_AFP=${OUTPUT_DIR}/`basename ${SCALE_PDF}`
          OUTPUT_AFP=`print ${OUTPUT_AFP} | sed s/pdf/afp/g`
          ${PROJ_DIR}/myscript.sh -i ${SCALE_PDF} -o ${OUTPUT_AFP} &
          sleep 30
      done
done

当我这样做时,我只认为一次只会同时执行myscript.sh的5个线程,但事情会发生变化,这个列表会执行30个线程,每个线程都会执行相当繁重的过程。如何将并发进程数限制为5?

3 个答案:

答案 0 :(得分:1)

虽然这在纯shell脚本中是可行的,但最简单的方法是使用GNU parallel或GNU make等并行化工具。 Makefile示例:

SOURCES = ${SOME_LIST}
STAMPS = $(SOME_LIST:=.did-run-stamp)

all : $(STAMPS)

%.did-run-stamp : %
    /full/path/myscript.sh -f $<

然后将make设为make -j 5

答案 1 :(得分:1)

使用GNU Parallel(根据需要调整-j。如果需要CPU数量,请将其删除):

for each in `ls ${INPUT_DIR}/MDX*.txt`
do
      java -Xms256m -Xmx1024m -cp ${CLASSPATH} com.wf.xn.etcc.Main -config=${CONFIG_FILE}
      ...
      for SCALE_PDF in `ls ${PROCESS_DIR}/*.pdf`
      do
          OUTPUT_AFP=${OUTPUT_DIR}/`basename ${SCALE_PDF}`
          OUTPUT_AFP=`print ${OUTPUT_AFP} | sed s/pdf/afp/g`
          sem --id myid -j 5 ${PROJ_DIR}/myscript.sh -i ${SCALE_PDF} -o ${OUTPUT_AFP}
      done
done
sem --wait --id myid

sem是GNU Parallel的一部分。

这将保留5个作业,直到只剩下5个作业。然后它将允许你的java在完成最后的5时运行。sem --wait将等到最后5个完成。

可替换地:

for each ...
   java ...
   ...
   ls ${PROCESS_DIR}/*.pdf |
   parallel -j 5 ${PROJ_DIR}/myscript.sh -i {} -o ${OUTPUT_DIR}/{/.}.afp
done

这将并行运行5个作业,只在所有作业完成后让java运行。

或者,您可以使用GNU Parallel的手册页中描述的队列技巧:https://www.gnu.org/software/parallel/man.html#example__gnu_parallel_as_queue_system_batch_manager

echo >jobqueue; tail -f jobqueue | parallel -j5 &
for each ...
   ...
   ls ${PROCESS_DIR}/*.pdf |
   parallel echo ${PROJ_DIR}/myscript.sh -i {} -o ${OUTPUT_DIR}/{/.}.afp >> jobqueue
done
echo killall -TERM parallel >> jobqueue
wait

这将运行java,然后添加要运行到队列的作业。添加作业后,将立即运行java。任何时候都会从队列中运行5个作业,直到队列为空。

您可以通过以下方式安装GNU Parallel:

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem

观看介绍视频以了解详情:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1并浏览教程(man parallel_tutorial)。你命令行爱你。

答案 2 :(得分:0)

如果您有 ksh93 ,请检查 JOBMAX 是否可用:

  

JOBMAX

This variable defines the maximum number running background
jobs that can run at a time. When this limit is reached, the
shell will wait for a job to complete before staring a new job.