Puede que esto se haya preguntado en un contexto similar, pero no he podido encontrar una respuesta después de unos 20 minutos de búsqueda, así que lo preguntaré.
He escrito un script de Python (digamos: scriptA.py) y un script (digamos scriptB.py)
En el scriptB quiero llamar al scriptA varias veces con diferentes argumentos, cada vez tarda una hora en ejecutarse, (es un script enorme, hace muchas cosas... no te preocupes) y quiero ser capaz de ejecutar el scriptA con todos los diferentes argumentos simultáneamente, pero necesito esperar hasta que TODOS ellos hayan terminado 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 los subprocess.call()
al mismo tiempo, y luego esperar hasta que todos ellos estén hechos, ¿cómo debo hacer esto?
Intenté usar hilos como en 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 todos han terminado de ejecutarse antes de ir a mi do_finish()
?
Coloca los hilos en una lista y luego utiliza el método de unión
threads = []
t = Thread(...)
threads.append(t)
...repeat as often as necessary...
# Start all threads
for x in threads:
x.start()
# Wait for all of them to finish
for x in threads:
x.join()
Es necesario utilizar el método join del objeto Thread
al final del script.
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()
t1.join()
t2.join()
t3.join()
Así el hilo principal esperará hasta que t1
, t2
y t3
terminen de ejecutarse.
Puedes tener una clase como la siguiente desde la que puedes añadir 'n' número de funciones o console_scripts que quieras ejecutar en paralelo pasión y empezar la ejecución y esperar a que se completen todos los trabajos..
from multiprocessing import Process
class ProcessParallel(object):
"""
To Process the functions parallely
"""
def __init__(self, *jobs):
"""
"""
self.jobs = jobs
self.processes = []
def fork_processes(self):
"""
Creates the process objects for given function deligates
"""
for job in self.jobs:
proc = Process(target=job)
self.processes.append(proc)
def start_all(self):
"""
Starts the functions process all together.
"""
for proc in self.processes:
proc.start()
def join_all(self):
"""
Waits untill all the functions executed.
"""
for proc in self.processes:
proc.join()
def two_sum(a=2, b=2):
return a + b
def multiply(a=2, b=2):
return a * b
#How to run:
if __name__ == '__main__':
#note: two_sum, multiply can be replace with any python console scripts which
#you wanted to run parallel..
procs = ProcessParallel(two_sum, multiply)
#Add all the process in list
procs.fork_processes()
#starts process execution
procs.start_all()
#wait until all the process got executed
procs.join_all()