다중 스레드 Python 프로그램에서 한 스레드가 내장 된 raw_input()을 사용하여 콘솔 입력을 요청하는 경우가 있습니다. raw_input 프롬프트에서 쉘에서^C를 입력하여 (즉, SIGINT 신호로) 프로그램을 닫을 수있게하고 싶습니다. 그러나 자식 스레드가 raw_input을 실행할 때^C를 입력하면 아무 일도 일어나지 않습니다. raw_input을 떠날 때까지 KeyboardInterrupt가 발생하지 않습니다. 다음의 프로그램, 예를 들어^C/KeyboardInterrupt가있는 자식 스레드에서 Python raw_input() 인터럽트
:
import threading
class T(threading.Thread):
def run(self):
x = raw_input()
print x
if __name__ == '__main__':
t = T()
t.start()
t.join()
타이핑^C 입력이 종료 할 때까지 아무것도하지 않는다. 그러나 T().run()
(즉, 단일 스레드의 경우 : 메인 스레드에서 raw_input 만 실행하면)^C는 즉시 프로그램을 닫습니다.
아마도 이것은 SIGINT가 주 스레드로 보내지기 때문입니다.이 스레드는 콘솔의 분기 된 스레드 블록을 읽는 동안 일시 중단 (GIL을 기다리는 중)됩니다. 주 스레드는 raw_input이 반환 된 후에 GIL을 잡을 때까지 시그널 핸들러를 실행하지 않습니다. (이 문제에 대해 내가 틀렸다면 수정하십시오. 파이썬의 스레딩 구현에 대한 전문가가 아닙니다.)
SIGINT를 처리하는 동안 raw_input 방식으로 stdin에서 읽는 방법이 있습니까? 주 스레드에 의해 전체 과정을 중단합니까? [내가 맥 OS X와 몇 가지 다른 Linuxes에 위의 동작을 관찰했습니다.]
편집 : 나는 위의 근본적인 문제를 mischaracterized했습니다. 추가 조사에서 신호 처리를 방해하는 것은 join()
에 대한 주 스레드의 호출입니다. Guido van Rossum 자신이 the underlying lock acquire in join is uninterruptible을 설명했습니다. 이것은 신호가 실제로 전체 스레드가 완료 될 때까지 연기된다는 것을 의미합니다. 따라서 이것은 실제로는 raw_input
과 아무 관련이 없습니다 (배경 스레드가 차단되어 조인이 완료되지 않는다는 사실과 전혀 관련이 없습니다).
단순히 스레드와 인터럽트를 결합하지 않습니다 ... [boromir.jpg] – JBernardo