2016-03-07 4 views
3

Я делаю сценарий оболочки и возникла неизвестная ситуация. Я должен выполнить определенное количество процессов, давайте предположим 12. Но я хочу каждый раз ограничивать выполнение «t». Поэтому, если «t» равно 3, мне пришлось бы выполнить 3 процесса, затем 3, 3 и, наконец, 3. Но я хотел бы сделать это автоматически, поэтому мне нужно отслеживать эти запущенные процессы и когда один из них закончен, я должен выполнить один оставшихся процессов.Как я могу контролировать количество запущенных процессов?

После некоторых исследований я обнаружил следующую команду:

launch backgroundprocess & 
PROC_ID=$! 
while kill -0 "$PROC_ID" >/dev/null 2>&1; do 
    echo "PROCESS IS RUNNING" 
done 
echo "PROCESS TERMINATED" 

Предложено cuonglm.

Это может помочь узнать, работает ли процесс или нет. Я попытался создать 12 процессов и сохранить их в 3 разных переменных, но он работает неправильно.

processors=3 
counter=0 

for A in {1..12} 
do 
    counter=$((counter+1)) 
    backgroundprocess & 
    PID[$A]=$! 

    while [ $counter -eq $processors ] 
    do 
     if kill -0 "$PID[1]" >/dev/null 2>&1; 
     then 
      counter=$(($counter-1)) 
      break 
     fi 
    done 
done 

Вы знаете, как я могу это делать?

ответ

1

Это улучшение вашего сценария.

ps -o pid= -p ${PID[$i]} возвращение PID если процесс есть.

num означает количество выполненных работ.

processors=3 
counter=0 
num=0 

for A in {1..12} 
do 
    counter=$((counter+1)) 
    sleep 4 & 
    if [ $num -eq 0 ] 
    then 
     PID[$A]=$! 
    else 
     PID[$num]=$! 
    fi 
    echo "$A starts" 
    echo $counter 

    while [ $counter -eq $processors ] 
    do 
     for i in `seq 1 $processors` 
     do 
      if [ ! `ps -o pid= -p ${PID[$i]}` ] 
      then 
       counter=$(($counter-1)) 
       echo "$i stopped" 
       num=$i 
       break 
      fi 
     done 
    done 
done 
2

Работы встроенная команда оболочки может использоваться для подсчета фоновых процессов.

Дополнительный файл используется для ожидания завершения фоновых процессов.

Дайте ему попробовать, тестируемый сценарий ниже:

#!/bin/bash -- 

tmp_file=/tmp/`date "+%Y%m%d%H%M%S$$"` 
rm -f "${tmp_file}" 
touch "${tmp_file}" 
max_nb_processes=12 
max_parallel_nb_processes=3 
nb_processes=0 
while [ $nb_processes -lt $max_nb_processes ] 
do 
    if [ `jobs -r | wc -l` -lt $max_parallel_nb_processes ] 
    then 
    (backgroundprocess ; printf "end" "" >> "${tmp_file}")& 
    ((nb_processes ++)) 
    else 
    read -t 10 line < "${tmp_file}" 
    fi 
done 
wait 

Для справки, первая версия.

Тестируемая версия ниже использовать некоторый опрос:

#!/bin/bash -- 

poll_time_second=10 
max_nb_processes=12 
max_parallel_nb_processes=3 
nb_processes=0 
while [ $nb_processes -lt $max_nb_processes ] 
do 
    if [ `jobs -r | wc -l` -lt $max_parallel_nb_processes ] 
    then 
    backgroundprocess & 
    ((nb_processes ++)) 
    else 
    sleep $poll_time_second 
    fi 
done 
wait 

до тех пор, пока существует менее 3 фоновые процессы, новый процесс запускается в фоновом режиме.

Когда есть 3 фоновых процесса, сценарий засыпает 10 секунд, прежде чем снова проверить.

Когда началось 12 фоновых процессов, сценарий ждет, что последние заканчиваются перед завершением.

+0

Пока нет ничего плохого в 'rm -f '$ {tmp_file}" ', корпус * brace * не имеет никакой цели. 'rm -f" $ tmp_file "является эквивалентным. (то же самое относится к 'touch' ниже) –

+0

В частности, если вы считаете, что сценарий генерирует имя файла, который представляет собой список цифр; Я имею в виду, что в имени файла нет специальных символов. Благодарим за информацию. Я также посмотрю на man-страницы. –

1

Пакеты легко, если вы не заботитесь о том, чтобы процессоры были заняты.

processors=3 
counter=0 

for A in {1..12} 
do 
    backgroundprocess & 
    ((counter++)) 
    if ((counter == processors)); then 
     wait # Block until all background jobs have completed 
     counter=0 
    fi 
done 
Смежные вопросы