#!/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
Beachten Sie, dass Sie vor "i =" 8 Leerzeichen durch zwei Tabulatoren ersetzen müssen, damit es funktioniert.
Es kann sogar Jobs auf Remote-Computern ausführen. Hier ein Beispiel für die Umcodierung einer MP3-Datei in OGG mit server2 und einem lokalen Computer, auf dem pro CPU-Kern 1 Job ausgeführt wird:
Ich habe keine Ahnung von "moreutils" und dass es bereits ein Werkzeug für den Job gibt. Schauen und vergleichen.
Vi. vor 14 Jahren
0
Das "Parallel" in moreutils ist nicht GNU Parallel und ist in seinen Optionen ziemlich eingeschränkt. Der obige Befehl wird nicht mit der Parallele von moreutils ausgeführt.
Ole Tange vor 14 Jahren
1
Eine weitere Option: `xargs --max-procs = 20`.
Vi. vor 8 Jahren
1
4
Benjamin Bannier
Not a bash solution, but you should use a Makefile, possibly with -l to not exceed some maximum load.
NJOBS=1000 .PHONY = jobs jobs = $(shell echo ) all: $(jobs) $(jobs): do_something $@
Then to start 20 jobs at a time do
$ make -j20
or to start as many jobs as possible without exceeding a load of 5
$ make -j -l5
Sieht aus wie die nicht hackige Lösung für jetzt.
Vi. vor 14 Jahren
0
`echo -e 'PHONY = jobs \ njobs = $ (shell echo ) \ n \ nall: $ \ n \ n $ : \ n \ t \ techo $ @; sleep \ `echo $$ RANDOM / 6553 | bc -l \ `'| make -f - -j20` Jetzt sieht es wieder hackiger aus.
Vi. vor 14 Jahren
2
@vi: oh mein ....
Benjamin Bannier vor 14 Jahren
0
Konvertiert Ihre Lösung in ein Skript. Jetzt kann es problemlos verwendet werden.
Vi. vor 14 Jahren
0
1
harrymc
One simple idea:
Check for i modulo 20 and execute the wait shell-command before do_something.
Entweder wird darauf gewartet, dass alle aktuellen Aufgaben abgeschlossen sind (das Erstellen von Sags in der Anzahl der Tasks) oder auf eine bestimmte Aufgabe, die länger dauern kann (in diesem Fall erneut).
Vi. vor 14 Jahren
0
@Vi: Shell warten bezieht sich auf alle Hintergrundaufgaben, die zu dieser Shell gehören.
harrymc vor 14 Jahren
0
1
msw
for i in ; do (echo $i ; sleep `expr $RANDOM % 5` ) & while [ `jobs | wc -l` -ge 20 ] ; do sleep 1 done done
Kann `while [\` jobs | sein wc -l \ `-ge 20]; do`
Vi. vor 14 Jahren
0
sicher, aber in meinem Beispiel muss ich dann 'njobs' zweimal berechnen, und Leistung ist in Shell-Skripts, die Schlafaufgaben ausführen, ziemlich wichtig;)
msw vor 14 Jahren
0
Ich meine, Ihre Version funktioniert nicht wie erwartet. Ich ändere "sleep 1" in "sleep 0.1" und es beginnt, die Anzahl der Njobs auf 40-50 anstatt 20 zu erhöhen. Wenn mehr als 20 Jobs vorhanden sind, müssen wir warten, bis alle Jobs beendet sind, und nicht nur 1 Sekunde warten.
Vi. vor 14 Jahren
0
1
Paul R
You could use ps to count how many processes you have running, and whenever this drops below a certain threshold you start another process.
Pseudo code:
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
posting the script in the question with formatting:
#!/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
Note that you must replace 8 spaces with 2 tabs before "i=".