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

questionAnswers(4)

yourAnswerToTheQuestion