paralelizar - programa de hilos en python
Cerrar todos los hilos con una interrupciĆ³n de teclado (1)
Una pregunta similar es "¿Cómo se mata un hilo?"
Se crea un controlador de salida en el hilo que está controlado por un objeto de bloqueo o evento del módulo de subprocesamiento. A continuación, simplemente quite el bloqueo o señalice el objeto del evento. Esto informa al hilo que debe detener el procesamiento y salir con gracia. Después de señalar el hilo en su programa principal, lo único que queda por hacer es usar el método thread.join()
en main
que esperará a que el hilo se cierre.
Un pequeño ejemplo:
import threading
import time
def timed_output(name, delay, run_event):
while run_event.is_set():
time.sleep(delay)
print name,": New Message!"
def main():
run_event = threading.Event()
run_event.set()
d1 = 1
t1 = threading.Thread(target = timed_output, args = ("bob",d1,run_event))
d2 = 2
t2 = threading.Thread(target = timed_output, args = ("paul",d2,run_event))
t1.start()
time.sleep(.5)
t2.start()
try:
while 1:
time.sleep(.1)
except KeyboardInterrupt:
print "attempting to close threads. Max wait =",max(d1,d2)
run_event.clear()
t1.join()
t2.join()
print "threads successfully closed"
if __name__ == ''__main__'':
main()
Si REALMENTE necesita la funcionalidad de matar un hilo, use multiprocesamiento. Le permite enviar SIGTERMs a "procesos" individuales (también es muy similar al módulo de subprocesamiento). En términos generales, el enhebrado es para cuando está vinculado a IO, y el multiprocesamiento es para cuando está verdaderamente vinculado al procesador.
Lo que estoy tratando de hacer aquí es usar una interrupción de teclado para salir de todos los hilos en curso en el programa. Esta es una versión simplificada de mi código donde se crea el hilo:
for i in taskDictionary:
try:
sleep(60)
thread = Thread(target = mainModule.executeThread)
thread.start()
except KeyboardInterrupt:
thread.__stop()
El programa en sí es mucho más complicado, ya que cuenta con toneladas de variables diferentes que afectan a los hilos e incluso tienen la opción de iniciarse en modo secuencial, donde las tareas no están enhebradas, sino que se lanzan una por una, por lo que puede haber algunos problemas con esta pequeña variación que acabo de conjurar. He hecho esto de forma que produjo 50/50 resultados. Las interrupciones funcionarían pero los hilos nunca saldrían limpiamente. Algunas veces continuarían pero detendrían la ejecución de hilos futuros, algunas veces saldrían con un error masivo con respecto a la interrupción, otras veces las interrupciones no harían nada. La última vez que ejecuté esto, el programa detuvo la ejecución de cualquier hilo futuro, pero no detuvo el hilo actual. ¿Hay alguna manera de salir de los hilos sin entrar en el módulo en el que se está ejecutando el hilo?