Únete a un grupo de procesos de python con un tiempo de espera

Estoy usando la biblioteca de multiprocesamiento de python para crear varios procesos.

from multiprocessing import Process processes = [Process(target=function) for function in FUNCTIONS] for p in processes: p.start() 

Quiero que se ejecuten durante algún tiempo y luego, si no se han completado, finalícelos.

 DURATION = 3600 

Una mala forma de hacerlo es la siguiente (mala porque si los procesos terminan más rápido que DURACIÓN, aún espera toda la DURACIÓN):

 from time import sleep sleep(duration) for p in processes: p.join(0) p.terminate() 

Otra mala manera de hacerlo (mala porque posiblemente puede tomar N * DURACIÓN para finalizar, donde N es el número de procesos):

 for p in processes: p.join(DURATION) p.terminate() 

¿Cuál es una buena manera de hacer esto?

Creo que esto hace lo que usted quiere sin ningún tipo de sondeo requerido, y solo esperará hasta su DURACIÓN especificada.

 time_waited = 0 then = time.time() for p in processes: if time_waited >= DURATION: p.join(0) p.terminate() p.join(DURATION - time_waited) time_waited = time.time() - then 

Esto sondeará cada segundo para ver si se completaron todos los procesos, hasta DURACIÓN. Si o todos los procesos han finalizado o DURACIÓN ha ocurrido, se une / mata a todos los procesos. No es perfecto, ya que tomará un poco más de un segundo en cada iteración del bucle for, pero estará bastante cerca.

 from time import sleep for _ in range(DURATION): if not any(i.is_alive() for i in processes): break sleep(1) for p in processes: p.join(0) p.terminate() 

Lo más fácil de hacer es probablemente tener un subproceso “maestro” que join(0) s todos los procesos y luego sale, y que el subproceso principal se join(3600) al subproceso principal.

 def wait_func(): for p in processes: p.join() wait_process = Process(target=wait_func) wait_process.start() wait_process.join(DURATION) for p in processes: p.terminate()