Esta podría ser una pregunta estúpida, pero estoy probando algunas de mis suposiciones sobre Python y estoy confundido sobre por qué el siguiente fragmento de código no se cerraría cuando se llamaba en el hilo, pero saldría cuando se llamaba en el hilo principal.
import sys, time
from threading import Thread
def testexit():
time.sleep(5)
sys.exit()
print "post thread exit"
t = Thread(target = testexit)
t.start()
t.join()
print "pre main exit, post thread exit"
sys.exit()
print "post main exit"
Los documentos de sys.exit () establecen que la llamada debe salir de Python. Puedo ver en la salida de este programa que "post salida del hilo" nunca se imprime, pero el hilo principal sigue funcionando incluso después de que el hilo llama a salir.
¿Se está creando una instancia separada del intérprete para cada hilo y la llamada a exit () solo está saliendo de esa instancia separada? Si es así, ¿cómo gestiona la implementación de subprocesos el acceso a los recursos compartidos? ¿Qué pasa si quisiera salir del programa del hilo (no es que realmente quiera, pero para entenderlo)?
fuente
os._exit
se usa dentro de las maldiciones, la consola no se restablece a un estado normal con esto. Tienes que ejecutarreset
en el shell de Unix para solucionar este problema.Al menos en Linux puedes hacer:
Esto envía
SIGINT
a al hilo principal que genera unKeyboardInterrupt
. Con eso tienes una limpieza adecuada. Incluso puedes manejar la señal si quieres.Por cierto: en Windows solo puede enviar una
SIGTERM
señal, que no se puede captar desde Python. En ese caso, simplemente puede usaros._exit
con el mismo efecto.fuente
¿Es el hecho de que esté impreso "pre salida principal, post salida del hilo" lo que le molesta?
A diferencia de otros lenguajes (como Java) donde el análogo a
sys.exit
(System.exit
, en el caso de Java) hace que la máquina virtual / proceso / intérprete se detenga de inmediato, Pythonsys.exit
solo lanza una excepción: una excepción de salida del sistema en particular.Aquí están los documentos para
sys.exit
(soloprint sys.exit.__doc__
):Esto tiene algunas consecuencias:
__del__
) se invocan potencialmente a medida que se desenrollan los marcos de pila que hacen referencia a esos objetosSystemExit
excepciónLa última es posiblemente la más sorprendente y es otra razón más por la que casi nunca debería tener una
except
declaración no calificada en su código Python.fuente
Mi método preferido es el paso de mensajes Erlang-ish. Ligeramente simplificado, lo hago así:
fuente
Queue
aquí. Solo un simplebool
servirá. El nombre clásico de esta variable esis_active
y su valor predeterminado inicial esTrue
.bool
(o cualquier otra operación atómica) funcionará perfectamente para este problema en particular. La razón por la que voy conQueue
s es que cuando se trabaja con agentes roscados tiendo a terminar necesitando varias señales diferentes (flush
,reconnect
,exit
, etc ...) casi inmediatamente.