сценарий оболочки: запустить пакет из N команд параллельно, дождаться завершения всех, запустить следующий N

9

Задача: запустить блоки, состоящие из 3-5 команд (параллельно / в фоновом режиме). Пример блока:

dd if=/dev/urandom of=/mnt/1/x bs=1024 count=1024000000 &
dd if=/dev/urandom of=/mnt/2/x bs=1024 count=1024000000 &
dd if=/dev/urandom of=/mnt/3/x bs=1024 count=1024000000 &

Когда это будет сделано, следующий блок должен работать. Я полагаю, это можно сделать с помощью файлов блокировки:

task1.sh:

real_task1 real_param1 ; rm /var/lock/myscript/task1.lock

task2.sh:

real_task2 real_param1 ; rm /var/lock/myscript/task2.lock

...

taskgen.sh:

# loop
 # while directory isn't empty - wait...
 gen_tasks.pl # build task files from some queue
 for i in 1 2 3; do touch /var/lock/myscript/task$i.lock ; done
 ./task1.sh &
 ./task2.sh &
 ./task3.sh &
 # if task1.sh doesn't exits then exit, else loop waits for files to be deleted

Существует ряд методов , чтобы проверить , если каталог пуст , можно найти здесь , не уверен , какой использовать;

Вопрос : есть ли лучший способ реализовать это?

PS Возможный способ сообщения о состоянии:

 command && report_good_state.sh taskid ;  report_state_done.sh taskid; rm /var/lock/myscript/taskN.lock
kagali-Сан -
источник
Ребята, просто не знаю, что сказать: все ответы верны, спасибо!
Кагали-сан

Ответы:

8

Это именно то, для чего предназначена параллельная среда GNU , поэтому я настоятельно рекомендую вам использовать ее. В частности, посмотрите, как он работает как семафор :

for i in {1..4}
do
  echo running $i
  sem -j3 df dd if=/dev/urandom of=/mnt/$i/x bs=1024 count=1024000000 ";" echo done
done
# sem --wait waits until all jobs are done.
sem --wait
Фил Холленбек
источник
8

Возможно какой-то вариант этого?

while true
do
  ./task1.sh&
  pid1=$!
  ./task2.sh&
  pid2=$!
  ./task3.sh&
  pid3=$!
  wait $pid1
  wait $pid2
  wait $pid3
done
Эдуардо Иванец
источник
Но да, параллельная GNU лучше, если она доступна.
Эдуардо Иванец
5

У вас есть какая-то конкретная причина не использовать что-то вроде параллельной GNU ? Если вы должны использовать bash, рассмотрите методы, подобные тем, которые описаны в этом сообщении в блоге (здесь полезны ожидание и именованные каналы).

justarobert
источник
3

«wait» ожидает завершения всех фоновых заданий. Образец:

спать 30 и спать 40 и спать 120 и ждать

Он ожидает завершения всех команд, т.е. не менее 120 секунд для этого примера.

Надеюсь это поможет.

Харри
источник
0

Мы попытались использовать утилиту GNU sem , как описано Филом Холленбеком выше, но обнаружили, что она слишком тяжелая (более 300 экземпляров нанесли вред машине). Я искал похожие инструменты для реализации облегченного счетного семафора, но не нашел ничего подходящего.

Так что я сам реализовал один, используя flock, это называется semaphoric .

Тим Банс
источник