Das folgende Skript zeigt eine Möglichkeit, dies mit Funktionen zu tun. Sie können entweder legen Sie die bgxupdate
und bgxlimit
Funktionen in Ihrem Skript oder sie in einer separaten Datei, die von Ihrem Skript mit bezogen ist:
. /path/to/bgx.sh
Es hat den Vorteil, dass Sie unabhängig mehrere Gruppen von Prozessen aufrechterhalten kann (man kann Führen Sie zum Beispiel eine Gruppe mit einem Limit von 10 und eine andere völlig separate Gruppe mit einem Limit von 3).
Es verwendet bash
Built-in, jobs
, um eine Liste der Unterprozesse zu erhalten, aber sie in einzelnen Variablen verwaltet. In der Schleife unten können Sie sehen, wie Sie die bgxlimit
-Funktion aufrufen:
eine leere Gruppenvariable einrichten.
übertragen Sie das auf bgxgrp
.
Anruf bgxlimit
mit dem Limit und Befehl, den Sie ausführen möchten.
übertragen Sie die neue Gruppe zurück auf Ihre Gruppenvariable.
Natürlich, wenn Sie nur eine Gruppe haben, verwenden Sie einfach bgxgrp
direkt, anstatt hinein und heraus zu übertragen.
#!/bin/bash
# bgxupdate - update active processes in a group.
# Works by transferring each process to new group
# if it is still active.
# in: bgxgrp - current group of processes.
# out: bgxgrp - new group of processes.
# out: bgxcount - number of processes in new group.
bgxupdate() {
bgxoldgrp=${bgxgrp}
bgxgrp=""
((bgxcount = 0))
bgxjobs=" $(jobs -pr | tr '\n' ' ')"
for bgxpid in ${bgxoldgrp} ; do
echo "${bgxjobs}" | grep " ${bgxpid} " >/dev/null 2>&1
if [[ $? -eq 0 ]] ; then
bgxgrp="${bgxgrp} ${bgxpid}"
((bgxcount = bgxcount + 1))
fi
done
}
# bgxlimit - start a sub-process with a limit.
# Loops, calling bgxupdate until there is a free
# slot to run another sub-process. Then runs it
# an updates the process group.
# in: $1 - the limit on processes.
# in: $2+ - the command to run for new process.
# in: bgxgrp - the current group of processes.
# out: bgxgrp - new group of processes
bgxlimit() {
bgxmax=$1 ; shift
bgxupdate
while [[ ${bgxcount} -ge ${bgxmax} ]] ; do
sleep 1
bgxupdate
done
if [[ "$1" != "-" ]] ; then
$* &
bgxgrp="${bgxgrp} $!"
fi
}
# Test program, create group and run 6 sleeps with
# limit of 3.
group1=""
echo 0 $(date | awk '{print $4}') '[' ${group1} ']'
echo
for i in 1 2 3 4 5 6 ; do
bgxgrp=${group1} ; bgxlimit 3 sleep ${i}0 ; group1=${bgxgrp}
echo ${i} $(date | awk '{print $4}') '[' ${group1} ']'
done
# Wait until all others are finished.
echo
bgxgrp=${group1} ; bgxupdate ; group1=${bgxgrp}
while [[ ${bgxcount} -ne 0 ]] ; do
oldcount=${bgxcount}
while [[ ${oldcount} -eq ${bgxcount} ]] ; do
sleep 1
bgxgrp=${group1} ; bgxupdate ; group1=${bgxgrp}
done
echo 9 $(date | awk '{print $4}') '[' ${group1} ']'
done
Hier ist ein Probelauf:
0 12:38:00 [ ]
1 12:38:00 [ 3368 ]
2 12:38:00 [ 3368 5880 ]
3 12:38:00 [ 3368 5880 2524 ]
4 12:38:10 [ 5880 2524 1560 ]
5 12:38:20 [ 2524 1560 5032 ]
6 12:38:30 [ 1560 5032 5212 ]
9 12:38:50 [ 5032 5212 ]
9 12:39:10 [ 5212 ]
9 12:39:30 [ ]
- Das Ganze beginnt bei 12.38.00 und, wie Sie sehen können, die ersten drei Prozesse sofort ausführen.
- Jeder Prozess schläft für
n*10
Sekunden, so dass der vierte Prozess erst bei den ersten Exits beginnt (zur Zeit t = 10 oder 12:38:10). Sie können sehen, dass der Prozess 3368 aus der Liste verschwunden ist, bevor 1560 hinzugefügt wurde.
- Ähnlich beginnt der fünfte Prozess (5032), wenn der zweite (5880) zum Zeitpunkt t = 20 austritt.
- Und schließlich beginnt der sechste Prozess (5212), wenn der dritte (2524) zum Zeitpunkt t = 30 ausläuft.
- Dann beginnt der Ablauf, vierter Prozess endet um t = 50 (begonnen bei 10, Dauer von 40), fünft bei t = 70 (gestartet bei 20, Dauer von 50) und sechster bei t = 90 (gestartet um 30, Dauer von 60).
Oder in Form Zeit online:
Process: 1 2 3 4 5 6
-------- - - - - - -
12:38:00^^^
12:38:10 v | |^
12:38:20 v | |^
12:38:30 v | |^
12:38:40 | | |
12:38:50 v | |
12:39:00 | |
12:39:10 v |
12:39:20 |
12:39:30 v
Ich denke, diese Frage könnte Ihnen helfen: http://StackOverflow.com/Questions/38160/Parallelize-Bash-Skript –
So viele verworrene Antworten, aber keine Möglichkeit zu sagen Bash "maximal zehn gleichzeitige Jobs!". Ich nehme an, da ist keiner. Schade, das wäre wirklich ein schönes Feature. –