Estou testando o threading Python com o seguinte script:
import threading
class FirstThread (threading.Thread):
def run (self):
while True:
print 'first'
class SecondThread (threading.Thread):
def run (self):
while True:
print 'second'
FirstThread().start()
SecondThread().start()
Ele está sendo executado no Python 2.7 no Kubuntu 11.10. Ctrl+ Cnão vai matá-lo. Também tentei adicionar um manipulador para sinais do sistema, mas isso não ajudou:
import signal
import sys
def signal_handler(signal, frame):
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
Para matar o processo estou eliminando-o por PID após enviar o programa para segundo plano com Ctrl+ Z, que não está sendo ignorado. Por que Ctrl+ está Csendo ignorado tão persistentemente? Como posso resolver isto?
Respostas:
Ctrl+ Ctermina o thread principal, mas como seus threads não estão no modo daemon, eles continuam em execução, e isso mantém o processo ativo. Podemos torná-los daemons:
Mas então há outro problema - uma vez que o thread principal iniciou seus threads, não há mais nada para fazer. Então, ele sai e os fios são destruídos instantaneamente. Então, vamos manter o tópico principal vivo:
Agora, ele manterá a impressão 'primeiro' e 'segundo' até que você pressione Ctrl+ C.
Edit: como comentadores apontaram, os threads do daemon podem não ter a chance de limpar coisas como arquivos temporários. Se você precisar disso, pegue o
KeyboardInterrupt
no thread principal e faça com que ele coordene a limpeza e o desligamento. Mas, em muitos casos, permitir que os threads do daemon morram repentinamente é provavelmente o suficiente.fonte
tempfile.TemporaryFile()
podem ser deixados no disco, por exemplo.daemon=True
paraThread.__init__
KeyboardInterrupt e os sinais são vistos apenas pelo processo (isto é, o thread principal) ... Dê uma olhada em Ctrl-c ie KeyboardInterrupt para matar threads em python
fonte
Eu acho que é melhor chamar join () em seus threads quando você espera que eles morram. Tomei alguma liberdade com o seu código para fazer os loops terminar (você também pode adicionar qualquer necessidade de limpeza necessária). O dado variável é verificado quanto à verdade em cada passagem e, quando for True, o programa é encerrado.
fonte
while True
é bobo, você deveriajoin
diretamente - e essa função substituída é um tanto questionável. Talvezdef join(self, force=False): if force: self.die = True
issojoin()
seja inalterado porjoin(force=True)
mata-los. Mas mesmo assim, é melhor informar os dois tópicos antes de entrar em qualquer um deles.Uma versão melhorada da resposta de @Thomas K:
is_any_thread_alive()
acordo com essa essência , que pode encerrar omain()
automaticamente.Códigos de exemplo:
fonte