threads threading thread start python3 new manager lock example acquire python python-2.6

threading - ¿Por qué sys.exit() no sale cuando se llama dentro de un hilo en Python?



threading.lock python example (5)

Esta podría ser una pregunta estúpida, pero estoy probando algunas de mis suposiciones sobre Python y estoy confundido en cuanto a por qué el siguiente fragmento de código no saldría cuando se llamaba en el hilo, pero saldría cuando se llamara 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 para sys.exit () indican que la llamada debe salir de Python. Puedo ver en la salida de este programa que "publicar salida de hilo" nunca se imprime, pero el hilo principal simplemente continúa incluso después de que sale el hilo.

¿Se está creando una instancia separada del intérprete para cada subproceso y la llamada a exit () solo está saliendo de esa instancia separada? De ser así, ¿cómo gestiona la implementación de subprocesos el acceso a los recursos compartidos? ¿Qué sucede si quiero salir del programa del hilo (no es lo que realmente quiero, pero entiendo)?


¿Qué sucede si quiero salir del programa del hilo (no es lo que realmente quiero, pero entiendo)?

Al menos en Linux podrías hacer algo como:

os.kill(os.getpid(), signal.SIGINT)

Esto envía un SIGINT al hilo principal donde se puede manejar como KeyboardInterrupt.

Por cierto: en Windows, solo puedes enviar una señal SIGTERM, que no se puede capturar desde Python. (allí preferiría llamar a os._exit como lo sugirió Helmut)


¿Qué sucede si quiero salir del programa del hilo (no es lo que realmente quiero, pero entiendo)?

Mi método preferido es pasar el mensaje Erlang-ish. Ligeramente similificado, lo hago así:

import sys, time import threading import Queue # thread-safe class CleanExit: pass ipq = Queue.Queue() def testexit(ipq): time.sleep(5) ipq.put(CleanExit) return threading.Thread(target=testexit, args=(ipq,)).start() while True: print "Working..." time.sleep(1) try: if ipq.get_nowait() == CleanExit: sys.exit() except Queue.Empty: pass


¿Qué sucede si quiero salir del programa desde el hilo?

Además del método descrito por Deestan, puede llamar a os._exit (observe el guión bajo). Antes de usarlo, asegúrese de comprender que no realiza limpiezas (como llamar a __del__ o similar).


¿El hecho de que "salida principal pre, salida de la rosca posterior" esté impreso 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 VM / proceso / intérprete se detenga inmediatamente, sys.exit de Python solo arroja una excepción: una excepción SystemExit en particular.

Aquí están los documentos para sys.exit (solo print sys.exit.__doc__ ):

Salga del intérprete levantando SystemExit (estado).
Si se omite el estado o Ninguno, se establece de manera predeterminada en cero (es decir, éxito).
Si el estado es numérico, se usará como estado de salida del sistema.
Si es otro tipo de objeto, se imprimirá y el sistema
el estado de salida será uno (es decir, falla).

Esto tiene algunas consecuencias:

  • en un hilo, simplemente elimina el hilo actual, no todo el proceso (suponiendo que llegue hasta la parte superior de la pila ...)
  • los destructores de objetos ( __del__ ) se invocan potencialmente a medida que los marcos de pila que hacen referencia a esos objetos se desenrollan
  • finalmente los bloques se ejecutan a medida que la pila se desenrolla
  • puedes atrapar una excepción SystemExit

El último es posiblemente el más sorprendente, y es una razón más por la que casi nunca debería tener una declaración de except no calificada en su código de Python.


sys.exit () genera la excepción SystemExit, al igual que thread.exit (). Entonces, cuando sys.exit () levanta esa excepción dentro de ese hilo, tiene el mismo efecto que llamar a thread.exit (), por lo que solo sale el hilo.