Interrupção de Python raw_input () em um thread filho com ^ C / KeyboardInterrupt
Em um programa Python multithread, às vezes um thread solicita a entrada do console usando oraw_input (). Gostaria de poder fechar o programa em um prompt raw_input digitando ^ C no shell (ou seja, com um sinal SIGINT). No entanto, quando o thread filho está executando raw_input, digitar ^ C não faz nada - o KeyboardInterrupt não é gerado até que eu aperte return (deixando raw_input).
Por exemplo, no seguinte programa:
import threading
class T(threading.Thread):
def run(self):
x = raw_input()
print x
if __name__ == '__main__':
t = T()
t.start()
t.join()
Digitar ^ C não faz nada até que a entrada seja concluída. No entanto, se chamarmosT().run()
(ou seja, o caso de thread único: basta executar raw_input no thread principal), ^ C fecha o programa imediatament
Presumivelmente, isso ocorre porque o SIGINT é enviado ao encadeamento principal, o qual é suspenso (aguardando o GIL) enquanto o encadeamento do bloco bifurcado no console é lido. O encadeamento principal não consegue executar seu manipulador de sinal até pegar o GIL após o retorno de raw_input. (Corrija-me se estiver errado sobre isso - não sou especialista na implementação de encadeamentos do Python.)
Existe uma maneira de ler stdin de maneira raw_input, enquanto permite que o SIGINT seja manipulado pelo thread principal e, assim, interrompa todo o process
[Observei o comportamento acima no Mac OS X e em alguns Linux diferentes.]
Editar Eu descaracterizei o problema subjacente acima. Em uma investigação mais aprofundada, é a chamada do thread principal parajoin()
que impede o manuseio do sinal: o próprio Guido van Rossum explicou que a aquisição do bloqueio subjacente na junção é ininterrupta. Isso significa que o sinal está sendo adiado até que todo o thread termine - portanto, isso realmente não tem nada a ver comraw_input
(apenas o fato de que o encadeamento em segundo plano está bloqueando para que a junção não seja concluída