Мне нужно выполнить множество однотипных команд за максимально короткое время, используя все доступные ресурсы.
Например, в моем случае обрабатываются изображения, когда я использую следующую команду:
for INPUT in *.jpg do; some_command; done
команды выполняются по одной и не используют все доступные ресурсы.
Но с другой стороны, выполнение for INPUT in *.jpg do; some_command &; done
приводит к тому, что ресурсы машины заканчиваются за очень короткое время.
Я знаю о at
команде batch
, но не уверен, что могу использовать ее в моем случае. Поправьте меня, если я не прав.
Поэтому я думал о том, чтобы поместить команды в некую очередь и выполнить только часть из них сразу. Я не знаю, как это сделать быстро, и в этом проблема. Я уверен, что кто-то уже сталкивался с подобной проблемой.
Пожалуйста, порекомендуйте.
решение1
GNU Parallel создан именно для этого:
parallel some_command {} ::: *.jpg
По умолчанию это одно задание на ядро ЦП. В вашем случае вы можете захотеть запустить на одно задание больше, чем у вас ядер:
parallel -j+1 some_command {} ::: *.jpg
GNU Parallel — это универсальный распараллеливатель, позволяющий легко запускать задания параллельно на одной машине или на нескольких машинах, к которым у вас есть доступ по SSH.
Если у вас есть 32 различных задания, которые вы хотите запустить на 4 ЦП, то прямой способ распараллеливания — запустить 8 заданий на каждом ЦП:
Вместо этого GNU Parallel запускает новый процесс после завершения предыдущего, сохраняя при этом активными ЦП и, таким образом, экономя время:
Монтаж
По соображениям безопасности вам следует установить GNU Parallel с помощью вашего менеджера пакетов, но если GNU Parallel не упакован для вашего дистрибутива, вы можете выполнить персональную установку, которая не требует доступа root. Это можно сделать за 10 секунд, выполнив следующее:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
Другие варианты установки см.http://git.savannah.gnu.org/cgit/parallel.git/tree/README
Узнать больше
Смотрите больше примеров:http://www.gnu.org/software/parallel/man.html
Посмотрите вступительные видеоролики:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Пройдите обучение:http://www.gnu.org/software/parallel/parallel_tutorial.html
Подпишитесь на рассылку, чтобы получить поддержку:https://lists.gnu.org/mailman/listinfo/parallel
решение2
Вы можете использовать GNU make с --jobs
возможностью параллельного запуска, но с ограничением по указанному количеству заданий. Вы можете настроить это количество так, чтобы оно не убило вашу машину.
Вот пример Makefile, который использует цели ah (например, это могут быть ваши выходные файлы) и запускает (фиктивный) набор команд для каждой цели:
all: a b c d e f g h
a b c d e f g h:
echo $@; sleep 10
NB Отступ командыдолженбыть символом TAB. СмотритеДокументация GNU makeдля получения подробной информации о синтаксисе Makefiles.
Вы можете вызвать make make --jobs 4
и получить следующий вывод (я использовал его time make --jobs 4
ниже, чтобы показать прошедшее время):
echo a; sleep 10
echo b; sleep 10
echo c; sleep 10
echo d; sleep 10
b
a
c
d
echo e; sleep 10
echo f; sleep 10
echo g; sleep 10
e
f
echo h; sleep 10
g
h
real 0m20.009s
user 0m0.010s
sys 0m0.011s
Первые четыре были выполнены параллельно, затем следующие четыре, так что общее затраченное время составило 20 секунд.