Sekwencyjny: for i in {1..1000}; do do_something $i; done
- za wolny
Równolegle: for i in {1..1000}; do do_something $i& done
- za duże obciążenie
Jak uruchamiać polecenia równolegle, ale nie więcej niż, na przykład, 20 instancji na chwilę?
Teraz zwykle używa hacka for i in {1..1000}; do do_something $i& sleep 5; done
, ale nie jest to dobre rozwiązanie.
Aktualizacja 2 : Przekształciła zaakceptowaną odpowiedź w skrypt: http://vi-server.org/vi/parallel
#!/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 ${MAKEOPTS:="-j20"}
cat << EOF | make -f - -s $MAKEOPTS
PHONY=jobs
jobs=\$(shell echo {1..$NUM})
all: \${jobs}
\${jobs}:
i=\$@ sh -c "\$\$CMD"
EOF
Pamiętaj, że musisz zastąpić 8 spacji 2 tabulatorami przed „i =”, aby działało.
parallel
moreutils nie jest GNU Parallel i ma dość ograniczone możliwości. Powyższe polecenie nie będzie działać równolegle z moreutils.xargs --max-procs=20
.Nie jest to bashowe rozwiązanie, ale powinieneś użyć Makefile, być może z
-l
nie przekraczającym maksymalnego obciążenia.Następnie rozpocznij 20 zadań jednocześnie
lub rozpocząć jak najwięcej zadań, nie przekraczając obciążenia 5
źródło
echo -e 'PHONY=jobs\njobs=$(shell echo {1..100000})\n\nall: ${jobs}\n\n${jobs}:\n\t\techo $@; sleep `echo $$RANDOM/6553 | bc -l`' | make -f - -j20
Teraz znów wygląda bardziej hacking.opublikowanie skryptu w pytaniu z formatowaniem:
Pamiętaj, że musisz zastąpić 8 spacji 2 tabulatorami przed „i =”.
źródło
Jeden prosty pomysł:
Sprawdź i modulo 20 i wykonaj polecenie shell shell wait przed do_something.
źródło
Możesz użyć,
ps
aby policzyć, ile procesów masz uruchomionych, a gdy tylko spadnie poniżej określonego progu, uruchom inny proces.Pseudo kod:
źródło
źródło
while [ `jobs | wc -l` -ge 20]; do
?njobs
dwukrotnie obliczyć , a wydajność jest dość ważna w skryptach powłoki wykonujących zadania uśpienia;)sleep 1
sięsleep 0.1
i zacznie średnich njobs do 40-50 zamiast 20. Jeśli istnieje więcej niż 20 miejsc pracy musimy czekać na każda praca zostanie zakończona, a nie tylko czekać na 1 sekundę.możesz to zrobić w ten sposób.
używając nazwanych potoków, za każdym razem uruchamia równolegle 20 podpowłok.
Mam nadzieję, że to pomoże :)
źródło