Esta pode ser uma pergunta estúpida, mas estou testando algumas de minhas suposições sobre Python e estou confuso sobre por que o seguinte trecho de código não sairia quando chamado no thread, mas sairia quando chamado no thread 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"
Os documentos para sys.exit () afirmam que a chamada deve sair do Python. Eu posso ver na saída deste programa que "post thread exit" nunca é impresso, mas o thread principal continua mesmo após a saída das chamadas de thread.
Uma instância separada do interpretador está sendo criada para cada thread e a chamada para exit () está apenas saindo dessa instância separada? Em caso afirmativo, como a implementação de encadeamento gerencia o acesso a recursos compartilhados? E se eu quisesse sair do programa do thread (não que eu realmente queira, mas apenas para que eu entenda)?
fonte
os._exit
é usado dentro de curses, o console não é redefinido para um estado normal com isso. Você tem que executarreset
no shell do Unix para corrigir isso.Pelo menos no Linux você pode fazer:
Isso envia um
SIGINT
para o tópico principal que gera aKeyboardInterrupt
. Com isso, você tem uma limpeza adequada. Você pode até mesmo controlar o sinal, se necessário.BTW: No Windows, você só pode enviar um
SIGTERM
sinal, que não pode ser capturado pelo Python. Nesse caso, você pode simplesmente usaros._exit
com o mesmo efeito.fonte
É o fato de que "pré saída principal, pós saída do tópico" é impresso o que está incomodando você?
Ao contrário de algumas outras linguagens (como Java) em que o analógico
sys.exit
(System.exit
, no caso de Java) faz com que a VM / processo / interpretador pare imediatamente, o Pythonsys.exit
apenas lança uma exceção: uma exceção SystemExit em particular.Aqui estão os documentos para
sys.exit
(apenasprint sys.exit.__doc__
):Isso tem algumas consequências:
__del__
) são potencialmente invocados quando os stack frames que fazem referência a esses objetos são desenroladosSystemExit
exceçãoO último é possivelmente o mais surpreendente e é mais um motivo pelo qual você quase nunca deve ter uma
except
instrução não qualificada em seu código Python.fonte
Meu método preferido é a passagem de mensagens tipo Erlang. Levemente simplificado, eu faço assim:
fonte
Queue
aqui. Apenas um simplesbool
bastará. O nome clássico dessa variável éis_active
e seu valor padrão inicial éTrue
.bool
(ou qualquer outra operação atômica) funcionará perfeitamente para este problema específico. A razão de eu ir comQueue
s é que quando se trabalha com agentes de rosca I tendem a acabar precisando de vários sinais diferentes (flush
,reconnect
,exit
, etc ...) quase imediatamente.