Pergunta

Se eu tenho um tópico em um loop infinito, existe uma maneira de encerrá -lo quando o programa principal termina (por exemplo, quando eu pressiono Ctrl+C)?

Foi útil?

Solução

Verifique esta pergunta. A resposta correta tem uma grande explicação sobre como encerrar os threads da maneira certa:Existe alguma maneira de matar um fio em Python?

Para fazer com que o thread pare no sinal de interrupção do teclado (Ctrl+C), você pode pegar a exceção "teclado interruptora" e a limpeza antes de sair. Assim:

try:
    start_thread()  
except (KeyboardInterrupt, SystemExit):
    cleanup_stop_thread()
    sys.exit()

Dessa forma, você pode controlar o que fazer sempre que o programa for encerrado abruptamente.

Você também pode usar o módulo de sinal interno que permite configurar manipuladores de sinal (no seu caso específico, o sinal SIGINT): http://docs.python.org/library/signal.html

Outras dicas

Se você fizer seus threads de trabalhadores que os fios, eles morrerão quando todos os seus threads não daemon (por exemplo, o encadeamento principal) tiverem saído.

http://docs.python.org/library/threading.html#threading.thread.daemon

Use o ATEXIT Módulo da biblioteca padrão do Python para registrar funções de "rescisão" que são chamadas (no tópico principal) em qualquer rescisão razoavelmente "limpa" do fio principal, incluindo uma exceção não capturada, como KeyboardInterrupt. Tais funções de rescisão podem (embora inevitavelmente no tópico principal!) Chame de qualquer stop função que você precisa; juntamente com a possibilidade de definir um tópico como daemon, isso fornece as ferramentas para projetar corretamente a funcionalidade do sistema necessária.

Se você gerar um tópico como assim - myThread = Thread(target = function) - E então faça myThread.start(); myThread.join(). Quando o Ctrl-C é iniciado, o fio principal não sai porque está esperando esse bloqueio myThread.join() ligar. Para corrigir isso, basta colocar um tempo limite na chamada .Join (). O tempo limite pode ser o tempo que você desejar. Se você quiser esperar indefinidamente, basta colocar um tempo limite muito longo, como 99999. Também é uma boa prática fazer myThread.daemon = True Portanto, todos os threads saem quando o thread principal (não daemon) sai.

Tente ativar o sub-thread como daemon-thread.

Por exemplo:

from threading import Thread

threaded = Thread(target=<your-method>)
threaded.daemon = True  # This thread dies when main thread (only non-daemon thread) exits.
threaded.start()

Ou (em uma linha):

from threading import Thread

threaded = Thread(target=<your-method>, daemon=True).start()

Quando o seu tópico principal termina ("por exemplo, quando eu pressiono Ctrl+C") que outros threads mata com a instrução acima.

Os threads Daemon são mortos sem graça, para que todas as instruções do finalizador não sejam executadas. Uma solução possível é verificar se o encadeamento principal está vivo em vez de loop infinito.

Por exemplo, para Python 3:

while threading.main_thread().isAlive():
    do.you.subthread.thing()
gracefully.close.the.thread()

Ver Verifique se o tópico principal ainda está vivo de outro tópico.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top