Параллельная обработка из очереди команд в Linux (bash, python, ruby ​​... что угодно) - PullRequest
42 голосов
/ 21 января 2009

У меня есть список / очередь из 200 команд, которые мне нужно запустить в оболочке на сервере Linux.

Я хочу, чтобы одновременно выполнялось не более 10 процессов (из очереди). Некоторые процессы завершатся за несколько секунд, другие - намного дольше.

Когда процесс завершится, я хочу, чтобы следующая команда «выскочила» из очереди и была выполнена.

У кого-нибудь есть код для решения этой проблемы?

Дальнейшая разработка:

Есть 200 работ, которые нужно выполнить, в какой-то очереди. Я хочу, чтобы одновременно работало не более 10 штук. Когда поток завершает часть работы, он должен запросить очередь для следующей части работы. Если в очереди больше нет работы, поток должен умереть. Когда все потоки исчезли, это означает, что вся работа была выполнена.

Фактическая проблема, которую я пытаюсь решить, - это использование imapsync для синхронизации 200 почтовых ящиков со старого почтового сервера на новый почтовый сервер. Некоторые пользователи имеют большие почтовые ящики и занимают много времени для синхронизации, другие имеют очень маленькие почтовые ящики и быстро синхронизируются.

Ответы [ 12 ]

0 голосов
/ 13 сентября 2017

Простая функция в zsh для распараллеливания заданий не более чем в 4 подоболочках с использованием файлов блокировки в /tmp.

Единственной нетривиальной частью являются флаги glob в первом тесте:

  • #q: включить глобализацию имени файла в тесте
  • [4]: возвращает только 4-й результат
  • N: игнорировать ошибку при пустом результате

Должно быть легко преобразовать его в posix, хотя это будет немного более многословно.

Не забывайте избегать кавычек в заданиях с помощью \".

#!/bin/zsh

setopt extendedglob

para() {
    lock=/tmp/para_$$_$((paracnt++))
    # sleep as long as the 4th lock file exists
    until [[ -z /tmp/para_$$_*(#q[4]N) ]] { sleep 0.1 }
    # Launch the job in a subshell
    ( touch $lock ; eval $* ; rm $lock ) &
    # Wait for subshell start and lock creation
    until [[ -f $lock ]] { sleep 0.001 }
}

para "print A0; sleep 1; print Z0"
para "print A1; sleep 2; print Z1"
para "print A2; sleep 3; print Z2"
para "print A3; sleep 4; print Z3"
para "print A4; sleep 3; print Z4"
para "print A5; sleep 2; print Z5"

# wait for all subshells to terminate
wait
0 голосов
/ 21 января 2009

Можете ли вы уточнить, что вы подразумеваете под параллельно ? Похоже, вам нужно реализовать какую-то блокировку в очереди, чтобы ваши записи не выбирались дважды и т. Д., А команды выполнялись только один раз.

Большинство систем очередей обманывают - они просто пишут гигантский список дел, а затем выбирают, например, десять предметов, обработайте их и выберите следующие десять предметов. Там нет распараллеливания.

Если вы предоставите более подробную информацию, я уверен, что мы можем вам помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...