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=True
enthreading.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 stop
funció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 Queue
y daemon
las discusiones: “error EOF” al salir del programa utilizando multiprocesamiento cola e hilo .
atexit
controladores 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 = True
para que todos los subprocesos salgan cuando sale el subproceso principal (que no es un demonio).
myThread.daemon = True
es una maravillosa solución a este problema.
.daemon=True
está 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 .