KSH: ограничение количества потоков, которые могут выполняться одновременно - PullRequest
0 голосов
/ 01 декабря 2011

У меня есть скрипт, который зацикливается, и каждая итерация вызывает поток, который работает в фоновом режиме, как показано ниже

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

Когда я это сделал, я только думаю, что этобудет одновременно выполняться только 5 потоков из myscript.sh, однако все изменится, и этот список выполнит 30 потоков, каждый из которых выполняет довольно тяжелый процесс.Как ограничить количество одновременных процессов до 5?

Ответы [ 3 ]

1 голос
/ 07 декабря 2011

Используйте GNU Parallel (отрегулируйте -j, как считаете нужным. Удалите его, если вы хотите количество процессоров):

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). Ты командная строка с любовью тебя за это.

1 голос
/ 01 декабря 2011

Хотя это возможно в сценариях с чистой оболочкой, самый простой подход - использовать инструмент параллелизации, такой как GNU parallel или GNU make. Пример создания файла:

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

all : $(STAMPS)

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

, а затем вызвать make как make -j 5.

0 голосов
/ 08 декабря 2011

Если у вас есть 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.
...