2012-06-18 9 views
10

Estoy escribiendo un script en shell en el que se está ejecutando un comando y demorando 2 min. cada vez. Además, no hay nada que podamos hacer con esto. Pero si quiero ejecutar este comando 100 veces en el script, el tiempo total sería de 200 minutos. y esto creará un gran problema. Nadie quiere esperar 200 minutos. Lo que quiero es ejecutar los 100 comandos de forma paralela para que la salida llegue en 2 minutos o puede ser un poco más de tiempo, pero no tome 200 minutos.Procesamiento en paralelo o subprocesamiento en el script de shell

se apreciará, si algún cuerpo puede ayudarme en esto de ninguna manera.

+0

[¿Qué has intentado] (http://mattgemmell.com/2008/12/08/what-have-you-tried/)? – ghoti

+0

Además, ¿qué shell estás usando? tcsh? zsh? pd-ksh? ¿pescado? – Graham

Respuesta

10

... correr los 100 comandos en paralelo de modo que la producción llegará en 2 minutos

Esto sólo es posible si usted tiene 200 procesadores en el sistema.

No existe tal utilidad/comando en el script de shell para ejecutar comandos en paralelo. Lo que puede hacer es ejecutar el comando en segundo plano:

for ((i=0;i<200;i++)) 
do 
    MyCommand & 
done 

Con & (fondo), cada ejecución está prevista tan pronto como sea posible. Pero esto no garantiza que su código se ejecutará en menos de 200 minutos. Depende de cuántos procesadores hay en su sistema.

Si tiene solo un procesador y cada ejecución del comando (que lleva 2 minutos) está haciendo algunos cálculos durante 2 minutos, entonces el procesador está trabajando, lo que significa que no hay ciclos desperdiciados. En este caso, ejecutar los comandos en paralelo no ayuda, porque solo hay un procesador que tampoco es gratuito. Entonces, los procesos estarán esperando que se ejecute su turno.

Si tiene más de un procesador, entonces el método anterior (para el ciclo) puede ayudar a reducir el tiempo total de ejecución.

+1

Si la secuencia de comandos está vinculada a IO, no necesita 200 procesadores. De hecho, se puede lograr una aceleración sustancial con solo 1 procesador. –

+0

@WilliamPursell Eso es correcto. Pero realmente depende de lo que el comando haga por eso * 2 minutos *. –

4

Como dijo @KingsIndian, puede realizar tareas en segundo plano, lo que hace que se ejecuten en paralelo. Más allá de esto, también se puede realizar un seguimiento de ellos por ID de proceso:

#!/bin/bash 

# Function to be backgrounded 
track() { 
    sleep $1 
    printf "\nFinished: %d\n" "$1" 
} 

start=$(date '+%s') 

rand3="$(jot -s\ -r 3 5 10)" 

# If you don't have `jot` (*BSD/OSX), substitute your own numbers here. 
#rand3="5 8 10" 

echo "Random numbers: $rand3" 

# Make an associative array in which you'll record pids. 
declare -A pids 

# Background an instance of the track() function for each number, record the pid. 
for n in $rand3; do 
    track $n & 
    pid=$! 
    echo "Backgrounded: $n (pid=$pid)" 
    pids[$pid]=$n 
done 

# Watch your stable of backgrounded processes. 
# If a pid goes away, remove it from the array. 
while [ -n "${pids[*]}" ]; do 
    sleep 1 
    for pid in "${!pids[@]}"; do 
    if ! ps "$pid" >/dev/null; then 
     unset pids[$pid] 
     echo "unset: $pid" 
    fi 
    done 
    if [ -z "${!pids[*]}" ]; then 
    break 
    fi 
    printf "\rStill waiting for: %s ... " "${pids[*]}" 
done 

printf "\r%-25s \n" "Done." 
printf "Total runtime: %d seconds\n" "$((`date '+%s'` - $start))" 

También debe echar un vistazo a la documentación en el reventón coprocesses.

13

GNU Parallel es lo que desea, a menos que desee reinventar la rueda. Éstos son algunos más detallada examples, pero el corto de él:

ls | parallel gzip # gzip all files in a directory 
Cuestiones relacionadas