Назад | Перейти на главную страницу

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

Задача: запускать блоки, состоящие из 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

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

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

P.S. Возможный метод сообщения о состоянии:

 command && report_good_state.sh taskid ;  report_state_done.sh taskid; rm /var/lock/myscript/taskN.lock

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

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

Возможно, какой-нибудь вариант на этот счет?

while true
do
  ./task1.sh&
  pid1=$!
  ./task2.sh&
  pid2=$!
  ./task3.sh&
  pid3=$!
  wait $pid1
  wait $pid2
  wait $pid3
done

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

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

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

Он ждет, пока все команды не будут выполнены, то есть не менее 120 секунд для этого примера.

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

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

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