Si tengo un hilo en un bucle infinito, ¿hay alguna manera de terminarlo cuando finaliza el programa principal (por ejemplo, cuando presiono Ctrl+ C)?
Respuestas:
Marque esta pregunta. La respuesta correcta tiene una gran explicación sobre cómo terminar los hilos de la manera correcta: ¿Hay alguna forma de eliminar un hilo en Python?
Para hacer que el hilo se detenga en la señal de interrupción del teclado (ctrl + c), puede detectar la excepción "KeyboardInterrupt" y limpiar antes de salir. Me gusta esto:
try:
start_thread()
except (KeyboardInterrupt, SystemExit):
cleanup_stop_thread()
sys.exit()
De esta forma, puede controlar qué hacer cuando el programa finaliza abruptamente.
También puede utilizar el módulo de señal incorporado que le permite configurar controladores de señal (en su caso específico, la señal SIGINT): http://docs.python.org/library/signal.html
cleanup_stop_thread()una función global que puedo usar? ¿O debería tener que implementarlo?
Si hace que sus subprocesos de trabajo sean subprocesos de demonio, estos morirán cuando todos los subprocesos que no son demonios (por ejemplo, el subproceso principal) hayan salido.
http://docs.python.org/library/threading.html#threading.Thread.daemon
isDaemon()es Falso, configúrelo como Verdadero por setDaemon(True).
isDaemon()y setDaemon()son viejos getters / setters (según el documento vinculado arriba), solo use daemon=Trueenthreading.Thread()
Intente habilitar el subproceso como daemon-thread.
Recomendado:
from threading import Thread
t = Thread(target=<your-method>)
t.daemon = True # This thread dies when main thread (only non-daemon thread) exits.
t.start()
En línea:
t = Thread(target=<your-method>, daemon=True).start()
API antigua:
t.setDaemon(True)
t.start()
Cuando su hilo principal termina ("es decir, cuando presiono Ctrl+ C"), las instrucciones anteriores también eliminarán otros hilos.
Utilice el módulo atexit de la biblioteca estándar de Python para registrar funciones de "terminación" que se llaman (en el hilo principal) en cualquier terminación razonablemente "limpia" del hilo principal, incluida una excepción no detectada como KeyboardInterrupt. Tales funciones de terminación pueden (¡aunque inevitablemente en el hilo principal!) Llamar a cualquier stopfunción que necesite; junto con la posibilidad de configurar un hilo como daemon, que te brinda las herramientas para diseñar adecuadamente la funcionalidad del sistema que necesitas.
atexit.register()llamadas pospuestas en los módulos de Python, lo que hace que su procedimiento de terminación se ejecute después del de multiprocessing. Corro en este trato con el problema Queuey daemonlas discusiones: “error EOF” al salir del programa utilizando multiprocesamiento cola e hilo .
atexitcontroladores no se llaman cuando los subprocesos que no son demonios están activos y el subproceso principal sale. Consulte Secuencia de comandos atascada al salir cuando se usa atexit para terminar subprocesos .
Si genera un hilo como myThread = Thread(target = function)ese, y luego hágalo myThread.start(); myThread.join(). Cuando se inicia CTRL-C, el hilo principal no sale porque está esperando esa myThread.join()llamada de bloqueo . Para solucionar esto, simplemente ponga un tiempo de espera en la llamada .join (). El tiempo de espera puede ser tan largo como desee. Si desea que espere indefinidamente, coloque un tiempo de espera realmente largo, como 99999. También es una buena práctica hacerlo myThread.daemon = Truepara que todos los subprocesos salgan cuando sale el subproceso principal (que no es un demonio).
myThread.daemon = Truees una maravillosa solución a este problema.
.daemon=Trueestá en una solución sólida. Consulte este hilo para obtener una explicación: stackoverflow.com/a/20598791/5562492
Los subprocesos de Daemon se eliminan sin gracia, por lo que las instrucciones del finalizador no se ejecutan. Una posible solución es verificar si el hilo principal está vivo en lugar de un bucle infinito.
Por ejemplo, para Python 3:
while threading.main_thread().isAlive():
do.you.subthread.thing()
gracefully.close.the.thread()
Consulte Comprobar si el subproceso principal sigue activo desde otro subproceso .