Определенно нет необходимости писать этот инструмент самостоятельно, есть несколько хороших вариантов.
make
make
может сделать это довольно легко, но для управления процессом он все же полагается на файлов . (Если вы хотите выполнить какую-либо операцию для каждого входного файла, который создает выходной файл, это может быть удивительным.) Параметр командной строки -j
будет запускать указанное количество задач, а параметр командной строки -l
средняя загрузка будет укажите среднюю загрузку системы, которую необходимо выполнить перед началом новых задач. (Это может быть хорошо, если вы хотите выполнить некоторую работу «в фоновом режиме». Не забудьте о команде nice(1)
, которая также может помочь здесь.)
Итак, быстрый (и непроверенный) Makefile
для конвертации изображений:
ALL=$(patsubst cimg%.jpg,thumb_cimg%.jpg,$(wildcard *.jpg))
.PHONY: all
all: $(ALL)
convert $< -resize 100x100 $@
Если вы запустите это с make
, оно будет запускаться по одному. Если вы запускаете с make -j8
, он запустит восемь отдельных заданий. Если вы запустите make -j
, он запустится сотнями. (При компиляции исходного кода я считаю, что удвоение числа ядер является отличной отправной точкой. Это дает каждому процессору что-то делать во время ожидания запросов дискового ввода-вывода. Разные машины и разные нагрузки могут работать по-разному.)
xargs
xargs
предоставляет параметр командной строки --max-procs
. Это лучше всего, если параллельные процессы можно разделить на основе одного входного потока с помощью либо отдельных входных команд ascii NUL
, либо разделенных входных команд новой строки. (Ну, опция -d
позволяет вам выбрать что-то еще, но эти два являются общими и простыми.) Это дает вам преимущество использования мощного синтаксиса выбора файлов find(1)
вместо написания смешных выражений, таких как Makefile
пример выше, или позволяет ваш ввод полностью не связаны с файлы . (Подумайте, есть ли у вас программа для деления больших составных чисел на простые множители - вписать эту задачу в make
будет в лучшем случае неудобно. xargs
может сделать это легко.)
Предыдущий пример может выглядеть примерно так:
find . -name '*jpg' -print0 | xargs -0 --max-procs 16 -I {} convert {} --resize 100x100 thumb_{}
parallel
Пакет moreutils
(доступен по крайней мере в Ubuntu) предоставляет команду parallel
. Он может выполняться двумя различными способами: либо выполнять указанную команду с разными аргументами, либо параллельно выполнять разные команды. Предыдущий пример может выглядеть так:
parallel -i -j 16 convert {} -resize 100x100 thumb_{} -- *.jpg
beanstalkd
Программа beanstalkd
использует совершенно другой подход: она предоставляет шину сообщений для отправки запросов и серверы заданий блок для заданий после ввода выполните задания, а затем вернитесь к ожиданию нового задания в очереди. Если вы хотите записать данные обратно в конкретный HTTP-запрос, который инициировал задание, это может быть не очень удобно, поскольку вы должны сами предоставить этот механизм (возможно, другую «трубу» на сервере beanstalkd
), но если Конечным результатом является отправка данных в базу данных, или по электронной почте, или что-то похожее асинхронное, это может быть проще всего интегрировать в существующее приложение.