script de shell: ejecute un lote de N comandos en paralelo, espere a que todos terminen, ejecute el siguiente N


9

Tarea: ejecutar bloques que consisten en 3-5 comandos (en paralelo / en segundo plano). Bloque de ejemplo:

dd if=/dev/urandom of=/mnt/1/x bs=1024 count=1024000000 &
dd if=/dev/urandom of=/mnt/2/x bs=1024 count=1024000000 &
dd if=/dev/urandom of=/mnt/3/x bs=1024 count=1024000000 &

Cuando termine, el siguiente bloque debería ejecutarse. Supongo que esto se puede hacer a través de archivos de bloqueo:

task1.sh:

real_task1 real_param1 ; rm /var/lock/myscript/task1.lock

task2.sh:

real_task2 real_param1 ; rm /var/lock/myscript/task2.lock

...

taskgen.sh:

# loop
 # while directory isn't empty - wait...
 gen_tasks.pl # build task files from some queue
 for i in 1 2 3; do touch /var/lock/myscript/task$i.lock ; done
 ./task1.sh &
 ./task2.sh &
 ./task3.sh &
 # if task1.sh doesn't exits then exit, else loop waits for files to be deleted

Aquí se pueden encontrar varios métodos para verificar si el directorio está vacío , no estoy seguro de cuál usar;

Pregunta : ¿alguna forma mejor de implementar esto?

PD Posible método de informe de estado:

 command && report_good_state.sh taskid ;  report_state_done.sh taskid; rm /var/lock/myscript/taskN.lock

Chicos, simplemente no sé qué decir: todas las respuestas son correctas, ¡gracias!
kagali-san

Respuestas:


8

Esto es exactamente para lo que está diseñado gnu parallel , por lo que le recomiendo que lo use. En particular, mira ejecutarlo como un semáforo :

for i in {1..4}
do
  echo running $i
  sem -j3 df dd if=/dev/urandom of=/mnt/$i/x bs=1024 count=1024000000 ";" echo done
done
# sem --wait waits until all jobs are done.
sem --wait

8

Tal vez alguna variación en esto?

while true
do
  ./task1.sh&
  pid1=$!
  ./task2.sh&
  pid2=$!
  ./task3.sh&
  pid3=$!
  wait $pid1
  wait $pid2
  wait $pid3
done

Pero sí, GNU paralelo es mejor si está disponible.
Eduardo Ivanec


3

"esperar" espera a que se completen todos los trabajos en segundo plano. Muestra:

dormir 30 y dormir 40 y dormir 120 y esperar

Espera hasta que se completen todos los comandos, es decir, al menos 120 segundos para este ejemplo.

Espero que esto ayude.


0

Intentamos usar la utilidad GNU sem , como lo describió Phil Hollenback anteriormente, pero lo encontramos demasiado pesado (más de 300 instancias paralizaron la máquina). Busqué herramientas similares para implementar un semáforo de conteo ligero, pero no pude encontrar nada adecuado.

Así que implementé uno usando flock, se llama semáforo .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.