Sequenziell: for i in {1..1000}; do do_something $i; done
- zu langsam
Parallel: for i in {1..1000}; do do_something $i& done
- zu viel Last
Wie werden Befehle parallel ausgeführt, jedoch nicht mehr als beispielsweise 20 Instanzen pro Moment?
Heutzutage wird normalerweise ein Hack verwendet for i in {1..1000}; do do_something $i& sleep 5; done
, aber dies ist keine gute Lösung.
Update 2 : Konvertierte die akzeptierte Antwort in ein Skript: 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
Beachten Sie, dass Sie 8 Leerzeichen durch 2 Tabulatoren vor "i =" ersetzen müssen, damit es funktioniert.
parallel
in moreutils ist nicht GNU Parallel und ist in seinen Optionen ziemlich eingeschränkt. Der Befehl oben wird nicht mit der Parallele von moreutils ausgeführt.xargs --max-procs=20
.Keine Bash-Lösung, aber Sie sollten ein Makefile verwenden, das möglicherweise
-l
die maximale Last nicht überschreitet.Dann starten Sie 20 Jobs gleichzeitig
oder um so viele Jobs wie möglich zu starten, ohne eine Last von 5 zu überschreiten
quelle
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
Jetzt sieht es wieder hackiger aus.Posten des Skripts in der Frage mit Formatierung:
Beachten Sie, dass Sie vor "i =" 8 Leerzeichen durch 2 Tabulatoren ersetzen müssen.
quelle
Eine einfache Idee:
Prüfe auf i modulo 20 und führe den wait shell-Befehl aus, bevor du etwas tust.
quelle
Mit
ps
dieser Option können Sie zählen, wie viele Prozesse ausgeführt werden. Wenn diese einen bestimmten Schwellenwert unterschreiten, starten Sie einen anderen Prozess.Pseudocode:
quelle
quelle
while [ `jobs | wc -l` -ge 20]; do
?njobs
zweimal rechnen , und die Leistung ist in Shell-Skripten, die Sleep-Tasks ausführen, ziemlich wichtig;)sleep 1
zusleep 0.1
und es beginnt mit einem durchschnittlichen Job von 40-50 statt 20. Wenn es mehr als 20 Jobs gibt, müssen wir warten, bis ein Job fertig ist, und nicht nur 1 Sekunde warten.du kannst es so machen.
Jedes Mal, wenn Named Pipes verwendet werden, werden 20 Subshells parallel ausgeführt.
Hoffe es hilft :)
quelle