#!/bin/bash NUM=$1; shift if [ -z "$NUM" ]; then echo "Usage: parallel <number_of_tasks> command" echo " Sets environment variable i from 1 to number_of_tasks" echo " Defaults to 20 processes at a time, use like \"MAKEOPTS='-j5' parallel ...\" to override." echo "Example: parallel 100 'echo \$i; sleep \`echo \$RANDOM/6553 | bc -l\`'" exit 1 fi export CMD="$@"; true $ cat << EOF | make -f - -s $MAKEOPTS PHONY=jobs jobs=\$(shell echo ) all: \$ \$: i=\$@ sh -c "\$\$CMD" EOF
Обратите внимание, что вы должны заменить 8 пробелов на 2 табуляции перед "i =", чтобы это работало.
Он даже может запускать задания на удаленных компьютерах. Вот пример перекодирования MP3 в OGG с использованием server2 и локального компьютера, выполняющего 1 задание на ядро ЦП:
Не знал о «moreutils» и о том, что уже есть инструмент для работы. Смотря и сравнивая.
Vi. 14 лет назад
0
Параллель в moreutils не является GNU Parallel и довольно ограничена в своих возможностях. Команда выше не будет работать с параллелью из moreutils.
Ole Tange 14 лет назад
1
Еще один вариант: `xargs --max-procs = 20`.
Vi. 8 лет назад
1
4
Benjamin Bannier
Не bash-решение, но вы должны использовать Makefile, возможно, -lчтобы он не превышал какую-то максимальную нагрузку.
NJOBS=1000 .PHONY = jobs jobs = $(shell echo ) all: $(jobs) $(jobs): do_something $@
Затем, чтобы начать 20 работ одновременно
$ make -j20
или начать как можно больше заданий, не превышая нагрузку 5
$ make -j -l5
Выглядит как нехакерское решение на данный момент.
Vi. 14 лет назад
0
`echo -e 'PHONY = jobs \ njobs = $ (shell echo ) \ n \ nall: $ \ n \ n $ : \ n \ t \ techo $ @; сон \ `эхо $$ RANDOM / 6553 | bc -l \ `'| make -f - -j20` Теперь это выглядит более хакерским.
Vi. 14 лет назад
2
@vi: о боже ....
Benjamin Bannier 14 лет назад
0
Преобразовал ваше решение в скрипт. Теперь его можно использовать с легкостью.
Vi. 14 лет назад
0
1
harrymc
Одна простая идея:
Проверьте по модулю 20 и выполните команду оболочки shell перед do_something.
Он будет либо ожидать завершения всех текущих задач (создавая провалы в графике количества задач), либо ждать одной конкретной задачи, которая может затянуться на более длительное время (снова создавая провалы в этом случае)
Vi. 14 лет назад
0
@Vi: Ожидание оболочки - это все фоновые задачи, которые принадлежат этой оболочке.
harrymc 14 лет назад
0
1
msw
for i in ; do (echo $i ; sleep `expr $RANDOM % 5` ) & while [ `jobs | wc -l` -ge 20 ] ; do sleep 1 done done
Может быть `while [\` jobs | wc -l \ `-ge 20]; do`?
Vi. 14 лет назад
0
конечно, но в моем примере мне пришлось бы дважды вычислять `njobs`, и производительность довольно важна в сценариях оболочки, которые запускают спящие задачи;)
msw 14 лет назад
0
Я имею в виду, ваша версия не работает, как ожидалось. Я изменяю `sleep 1` на` sleep 0.1`, и он начинает усреднять njobs до 40-50 вместо 20. Если существует более 20 рабочих мест, нам нужно дождаться окончания любой работы, а не просто ждать 1 секунду.
Vi. 14 лет назад
0
1
Paul R
Вы можете использовать, psчтобы подсчитать, сколько процессов у вас запущено, и всякий раз, когда это падает ниже определенного порога, вы запускаете другой процесс.
Псевдокод:
i = 1 MAX_PROCESSES=20 NUM_TASKS=1000 do get num_processes using ps if num_processes < MAX_PROCESSES start process $i $i = $i + 1 endif sleep 1 # add this to prevent thrashing with ps until $i > NUM_TASKS
1
warren
размещение сценария в вопросе с форматированием:
#!/bin/bash NUM=$1; shift if [ -z "$NUM" ]; then echo "Usage: parallel <number_of_tasks> command" echo " Sets environment variable i from 1 to number_of_tasks" echo " Defaults to 20 processes at a time, use like \"MAKEOPTS='-j5' parallel ...\" to override." echo "Example: parallel 100 'echo \$i; sleep \`echo \$RANDOM/6553 | bc -l\`'" exit 1 fi export CMD="$@"; true $ cat << EOF | make -f - -s $MAKEOPTS PHONY=jobs jobs=\$(shell echo ) all: \$ \$: i=\$@ sh -c "\$\$CMD" EOF
Обратите внимание, что перед «i =» вы должны заменить 8 пробелов на 2 табуляции.