Можете ли вы создать пул процессов с помощью сценариев оболочки?

2

Скажем, у меня есть большое количество заданий (десятки или сотни), которые нужно выполнять, но они требуют значительных ресурсов процессора и только несколько из них могут быть запущены одновременно. Есть ли простой способ запустить Xработу сразу и начать новую после ее завершения? Единственное, что я могу придумать, это что-то вроде ниже (псевдокод):

jobs=(...);
MAX_JOBS=4;
cur_jobs=0;
pids=(); # hash/associative array
while (jobs); do
    while (cur_jobs < MAX_JOBS); do
        pop and spawn job and store PID and anything else needed;
        cur_jobs++;
    done
    sleep 5;
    for each PID:
        if no longer active; then
            remove PID;
            cur_jobs--;
done

Я чувствую, что слишком усложняю решение, как я часто это делаю. Целевой системой является FreeBSD, если может быть какой-то порт, который выполняет всю тяжелую работу, но предпочтительным является универсальное решение или общая идиома.

Джейсон Лефлер
источник
2
GNU Parallel, кажется, инструмент для этого, но я не уверен. У него есть порт .
Муру
1
Я бы написал для этого make-файл, а затем запустил бы make -f 44 параллельных задания.
wurtel
Makefile, это великолепно. Я бы никогда не подумал об этом.
Джейсон Лефлер

Ответы:

6

Если у вас есть GNU Parallel, вы можете сделать это:

parallel do_it {} --option foo < argumentlist

GNU Parallel - это общий параллелизатор, который позволяет легко запускать задания параллельно на одной и той же машине или на нескольких машинах, к которым у вас есть доступ по ssh.

Если у вас есть 32 различных задания, которые вы хотите запустить на 4 процессорах, прямой способ распараллеливания - запустить 8 заданий на каждом процессоре:

Простое планирование

GNU Parallel вместо этого порождает новый процесс после его завершения - поддерживая процессоры активными и, таким образом, экономя время:

Параллельное планирование GNU

Монтаж

Если 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

Оле Танге
источник
1
На странице GNU Parallel перечислены порты FreeBSD .
Муру
0

Можно, но это сложно и хрупко. Есть несколько вариантов, один из них есть xargs.

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

http://prll.sourceforge.net/shell_parallel.html

Парень, очевидно, создал новый инструмент, prllкоторый может принимать произвольные функции оболочки для параллельного выполнения (с автоматически определяемым или определяемым пользователем размером пула), который использует процесс управления, который синхронизирует все ввод и вывод.

Проверьте это здесь: https://gitorious.org/prll/pages/Home

Орион
источник
Некоторые из проблем с xargs описаны здесь: gnu.org/software/parallel/… Некоторые из проблем с prll описаны здесь gnu.org/software/parallel/…
Уле Танге
0

У меня была точно такая же ситуация, как и у вас, но задания, которые мне нужно выполнять параллельно, это команды, которые запускают скрипты ruby. Во-первых, я должен признать, что он не идеален, а хрупок.

То, что я сделал в своем коде ruby, было:

counting_process = IO.popen "ps -e | grep 'YourCMDPattern' -c"
count_of_processes = counting_process.readlines[0].to_i

Затем в цикле while я периодически проверяю количество процессов, а затем запускаю команду оболочки для запуска определенного количества новых процессов с помощью IO.popen в ruby, когда число меньше количества параллельного выполнения, которое я хочу сохранить.

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

GNU Parallel кажется лучшим вариантом для вас, если ruby ​​не задействован.

M.PG
источник