Kleine und große Linux AHAs
Beiträge getaggt mit parallelizer
Bash Jobs Parallelisieren
29. Apr
Es gibt Anforderungen bei denen es nötig ist viele Befehle – möglicherweise mit verschiedenen Parametern – schnell ab zu arbeiten. Dabei kann man sich der Anzahl an Cores in einem Server (oder auch PC) bedienen. Eine Anforderung wäre zum Beispiel, dass immer so viele Prozesse gestartet werden, wie auch Prozessoren verfügbar sind. Das ganze möglichst ohne viel Drumherum – also ohne viel Installationsaufwand.
Eine ganz simple Möglichkeit stellt folgendes Script dar. Als Parameter wird jeweils der komplette Befehl angegeben. Standardmäßig laufen immer so viele Prozesse gleichzeitig wie Prozessoren vorhanden sind. Diese Zahl kann aber auch manuell vorgegeben werden. Das restliche Management übernimmt das Script selbst.
#!/bin/bash
#
# Ronny Becker, 05.2009
#
NUM=0
QUEUE=""
MAX_NPROC="none"
USAGE="A simple wrapper for running processes in parallel.
Usage: `basename $0` [-h] [-q] [-r] [-j nb_jobs] command command command command command command command command ...
-h Shows this help
-j nb_jobs Set number of simultanious jobs [def. CPU Count]
-q be quiet - do not output any information (but errors)
Examples:
`basename $0` somecommand somecommand somecommand ..."
# subs
function queue {
QUEUE="$QUEUE $1"
NUM=$(($NUM+1))
}
function regeneratequeue {
OLDREQUEUE=$QUEUE
QUEUE=""
NUM=0
for PID in $OLDREQUEUE
do
if [ -d /proc/$PID ] ; then
QUEUE="$QUEUE $PID"
NUM=$(($NUM+1))
fi
done
}
function checkqueue {
OLDCHQUEUE=$QUEUE
for PID in $OLDCHQUEUE
do
if [ ! -d /proc/$PID ] ; then
regeneratequeue # at least one PID has finished
break
fi
done
}
# parse command line
if [ $# -eq 0 ]; then # must be at least one arg
echo "$USAGE" >&2
exit 1
fi
while getopts j:qh OPT; do # "j:" waits for an argument "h" doesnt
case $OPT in
h) echo "$USAGE"
exit 0 ;;
j) MAX_NPROC=$OPTARG ;;
q) BE_QUIET=1 ;;
\?) # getopts issues an error message
echo "$USAGE" >&2
exit 1 ;;
esac
done
# get cpu information (cpu count = MAX_NPROC)
if [[ "$MAX_NPROC" =~ "none" ]]; then
CPUs=`cat /proc/cpuinfo | grep -c "processor.*[0-9]$" 2>/dev/null`
if [ $CPUs -gt 0 ]
then
MAX_NPROC=$CPUs
if [ ! $BE_QUIET ]; then echo "Found $MAX_NPROC CPUs - using $MAX_NPROC parallel threads"; fi
else
MAX_NPROC=2
if [ ! $BE_QUIET ]; then echo "Setting number of simultanous jobs to 2 - could not get CPU information"; fi
fi
fi
# Main program
shift `expr $OPTIND - 1` # shift input args, ignore processed args
# Count all Jobs
CMD_COUNT=$#
CMD_COUNT_ACT=0
# run forest run !!
while [ $# -gt 0 ] # for the rest of the arguments
do
# statistics
CMD_COUNT_ACT=$(($CMD_COUNT_ACT + 1))
# define command
CMD="$1"
shift
if [ ! $BE_QUIET ]; then echo -e "`date \"+%d.%m.%Y %H:%M:%S\"`: \033[1m [${CMD_COUNT_ACT}/${CMD_COUNT}]\033[0m Starting \033[1m${CMD}\033[0m"; fi
# run command
eval "$CMD &"
PID=$!
queue $PID
while [ $NUM -ge $MAX_NPROC ]; do
checkqueue
sleep 0.6
done
done
wait # wait for all processes to finish before exit
if [ ! $BE_QUIET ]; then echo -e "`date \"+%d.%m.%Y %H:%M:%S\"`: \033[1m all procs finished \033[0m"; fi
Das Original Script funktioniert ein wenig anders. Zu finden ist es hier


