Se eu tiver um thread em um loop infinito, há uma maneira de encerrá-lo quando o programa principal terminar (por exemplo, quando pressiono Ctrl+ C)?
86
Se eu tiver um thread em um loop infinito, há uma maneira de encerrá-lo quando o programa principal terminar (por exemplo, quando pressiono Ctrl+ C)?
Verifique esta questão. A resposta correta tem uma ótima explicação sobre como encerrar threads da maneira certa: Existe alguma maneira de eliminar um Thread em Python?
Para fazer o thread parar no sinal de interrupção de teclado (ctrl + c), você pode capturar a exceção "KeyboardInterrupt" e limpar antes de sair. Como isso:
try:
start_thread()
except (KeyboardInterrupt, SystemExit):
cleanup_stop_thread()
sys.exit()
Desta forma, você pode controlar o que fazer sempre que o programa for encerrado abruptamente.
Você também pode usar o módulo de sinal integrado que permite configurar manipuladores de sinal (no seu caso específico, o sinal SIGINT): http://docs.python.org/library/signal.html
cleanup_stop_thread()
uma função global que posso usar? ou devo implementá-lo?Se você criar threads daemon de threads de trabalho, elas morrerão quando todas as threads não-daemon (por exemplo, a thread principal) forem encerradas.
http://docs.python.org/library/threading.html#threading.Thread.daemon
fonte
isDaemon()
é False, defina-o como True porsetDaemon(True)
.isDaemon()
esetDaemon()
são getters / setters antigos (conforme o documento vinculado acima), basta usardaemon=True
inthreading.Thread()
Tente habilitar o sub-thread como daemon-thread.
Por exemplo:
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()
Na linha:
t = Thread(target=<your-method>, daemon=True).start()
API antiga:
t.setDaemon(True) t.start()
Quando seu thread principal termina ("isto é, quando eu pressiono Ctrl+ C"), outros threads também serão encerrados pelas instruções acima.
fonte
Use o módulo atexit da biblioteca padrão do Python para registrar funções de "término" que são chamadas (no encadeamento principal) em qualquer encerramento razoavelmente "limpo" do encadeamento principal, incluindo uma exceção não capturada como
KeyboardInterrupt
. Essas funções de encerramento podem (embora inevitavelmente no thread principal!) Chamar qualquerstop
função que você precisar; junto com a possibilidade de definir um thread comodaemon
, que lhe dá as ferramentas para projetar adequadamente a funcionalidade do sistema que você precisa.fonte
atexit.register()
chamadas posteriores aos módulos Python, fazendo com que seu procedimento de encerramento seja executado após omultiprocessing
de um. Eu corro neste problema lidando comQueue
edaemon
threads: “EOF error” na saída do programa usando multiprocessing Queue and Thread .atexit
manipuladores não são chamados quando threads não daemon estão ativos e a thread principal sai. Consulte Script travado na saída ao usar atexit para encerrar threads .Se você gerar um Thread como este -
myThread = Thread(target = function)
- e então o façamyThread.start(); myThread.join()
. Quando CTRL-C é iniciado, o thread principal não sai porque está aguardando aquelamyThread.join()
chamada de bloqueio . Para corrigir isso, basta colocar um tempo limite na chamada .join (). O tempo limite pode ser tão longo quanto você desejar. Se você quiser esperar indefinidamente, coloque um tempo limite realmente longo, como 99999. Também é uma boa prática fazermyThread.daemon = True
para que todos os threads saiam quando o thread principal (não-daemon) for encerrado.fonte
myThread.daemon = True
é uma solução maravilhosa para este problema..daemon=True
não é uma solução sólida. Verifique este tópico para obter uma explicação: stackoverflow.com/a/20598791/5562492Os threads do daemon são eliminados de maneira desagradável, portanto, as instruções do finalizador não são executadas. Uma possível solução é verificar se o thread principal está ativo em vez de um loop infinito.
Por exemplo, para Python 3:
while threading.main_thread().isAlive(): do.you.subthread.thing() gracefully.close.the.thread()
Consulte Verificar se o thread principal ainda está ativo em outro thread .
fonte