Es posible que esto se haya preguntado en un contexto similar, pero no pude encontrar una respuesta después de unos 20 minutos de búsqueda, así que preguntaré.
He escrito un script de Python (digamos: scriptA.py) y un script (digamos scriptB.py)
En scriptB quiero llamar a scriptA varias veces con diferentes argumentos, cada vez tarda aproximadamente una hora en ejecutarse (es un script enorme, hace muchas cosas ... no se preocupe) y quiero poder ejecutar el scriptA con todos los diferentes argumentos simultáneamente, pero necesito esperar hasta que TODOS estén listos antes de continuar; mi código:
import subprocess
#setup
do_setup()
#run scriptA
subprocess.call(scriptA + argumentsA)
subprocess.call(scriptA + argumentsB)
subprocess.call(scriptA + argumentsC)
#finish
do_finish()
Quiero ejecutar todos subprocess.call()
al mismo tiempo, y luego esperar hasta que terminen, ¿cómo debo hacer esto?
Traté de usar subprocesos como el ejemplo aquí :
from threading import Thread
import subprocess
def call_script(args)
subprocess.call(args)
#run scriptA
t1 = Thread(target=call_script, args=(scriptA + argumentsA))
t2 = Thread(target=call_script, args=(scriptA + argumentsB))
t3 = Thread(target=call_script, args=(scriptA + argumentsC))
t1.start()
t2.start()
t3.start()
Pero no creo que esto sea correcto.
¿Cómo sé que han terminado de correr antes de ir a mi do_finish()
?
fuente
join
bloques hasta que el hilo finalice la ejecución. De todos modos, tendrá que esperar todos los hilos. Sit1
termina primero, comenzará a esperart2
(que puede que ya haya terminado e inmediatamente procederá a esperart3
). Sit1
tomó más tiempo para ejecutar, cuando regrese de que tantot1
yt2
volverá inmediatamente sin bloquear.join
de alguna manera adjunta el proceso actual al hilo y espera hasta que esté listo, y si t2 termina antes de t1, cuando t1 esté listo, verificará que t2 esté listo. que es, y luego marque t3..etc..etc .. y luego sólo cuando todo esté hecho continuará. increíble.Coloque los hilos en una lista y luego use el método Join
fuente
for x in threads: x.join()
comprensión de la lista en lugar de usarlaEn Python3, desde Python 3.2 hay un nuevo enfoque para alcanzar el mismo resultado, que personalmente prefiero al paquete tradicional de creación / inicio / unión de subprocesos
concurrent.futures
: https://docs.python.org/3/library/concurrent.futures .htmlUsar un
ThreadPoolExecutor
código sería:La salida del código anterior es algo como:
Una de las ventajas es que puede controlar el rendimiento estableciendo el máximo de trabajadores simultáneos.
fuente
with
declaración se ejecuta cuando todas las tareas han finalizado.with
instrucción por diseño en este caso. De todos modos, siempre puede abrir una nueva pregunta en SO y publicar su código para que podamos ayudarlo a averiguar qué está sucediendo en su caso.concurrent.futures.wait
función, puede ver un ejemplo real aquí Documentos oficiales: docs.python.org/3/library/…Prefiero usar la comprensión de la lista basada en una lista de entrada:
fuente
for t in threads:t.start()
¿no es mejor?Puede tener una clase como la siguiente desde la que puede agregar 'n' número de funciones o scripts de consola que desea ejecutar en paralelo y comenzar la ejecución y esperar a que se completen todos los trabajos.
fuente
De la
threading
documentación del móduloEntonces, para detectar esos dos casos en los que no está interesado en mantener una lista de los hilos que crea:
Después de lo cual:
fuente
Tal vez algo como
fuente
Me encontré con el mismo problema en el que necesitaba esperar todos los subprocesos que se crearon usando el bucle for. Acabo de probar el siguiente código. Puede que no sea la solución perfecta, pero pensé que sería una solución simple. Probar:
fuente