Estoy probando el subproceso de Python con el siguiente script:
import threading
class FirstThread (threading.Thread):
def run (self):
while True:
print 'first'
class SecondThread (threading.Thread):
def run (self):
while True:
print 'second'
FirstThread().start()
SecondThread().start()
Esto se ejecuta en Python 2.7 en Kubuntu 11.10. Ctrl+ Cno lo matará. También intenté agregar un controlador para las señales del sistema, pero eso no ayudó:
import signal
import sys
def signal_handler(signal, frame):
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
Para matar el proceso, lo estoy matando por PID después de enviar el programa al fondo con Ctrl+ Z, que no se ignora. ¿Por qué Ctrl+ Cse ignora tan persistentemente? ¿Cómo puedo resolver esto?
Respuestas:
Ctrl+ Ctermina el hilo principal, pero debido a que sus hilos no están en modo demonio, continúan ejecutándose y eso mantiene vivo el proceso. Podemos convertirlos en demonios:
Pero luego hay otro problema: una vez que el hilo principal ha iniciado sus hilos, no hay nada más que pueda hacer. Entonces sale, y los hilos se destruyen instantáneamente. Así que mantengamos vivo el hilo principal:
Ahora seguirá imprimiendo 'primero' y 'segundo' hasta que presione Ctrl+ C.
Editar: como han señalado los comentaristas, es posible que los subprocesos del demonio no tengan la oportunidad de limpiar cosas como archivos temporales. Si lo necesita, coja el
KeyboardInterrupt
hilo principal y haga que coordine la limpieza y el apagado. Pero en muchos casos, dejar que los hilos del demonio mueran de repente es probablemente suficiente.fuente
tempfile.TemporaryFile()
pueden dejarse en el disco, por ejemplo.daemon=True
aThread.__init__
KeyboardInterrupt y las señales solo son vistas por el proceso (es decir, el hilo principal) ... Eche un vistazo a Ctrl-c, es decir, KeyboardInterrupt para matar hilos en Python
fuente
Creo que es mejor llamar a join () en tus hilos cuando esperas que mueran. Me he tomado un poco de libertad con su código para hacer que los bucles terminen (también puede agregar las necesidades de limpieza que se requieran allí). Se comprueba la verdad de la variable die en cada pasada y cuando es True, el programa se cierra.
fuente
while True
es una tontería, debería hacerlojoin
directamente, y esa función anulada es algo cuestionable. Tal vezdef join(self, force=False): if force: self.die = True
por esojoin()
no cambia por losjoin(force=True)
mata. Pero incluso entonces, es mejor informar ambos hilos antes de unirse a cualquiera.Una versión mejorada de la respuesta de @Thomas K:
is_any_thread_alive()
acuerdo con esta esencia , que puede terminarmain()
automáticamente.Códigos de ejemplo:
fuente