2011-09-30 4 views

답변

3

Ctrl 키 + CSIGINT 아닌가? 어쨌든

, 적절한 신호 처리기를 설치할 수 있고, 핸들러 :

  • 종료, 그들은 정기적으로
  • 그것을 확인 있는지 확인하거나 넣어 노동자를 지시하는 글로벌 플래그를 설정 그들이
  • 토큰 또는 그 토큰을 밀어 메인 스레드를 지시하는 플래그를 설정 마법, 메인 스레드 검사 확인을 팝업 때 10 종료 큐에 토큰, 그리고 노동자 출구가 그 플래그

등입니다. 주로 방해하는 응용 프로그램의 구조에 따라 다릅니다.

+0

오른쪽! 편집 된 SIGINT – gbr

+0

+1 대기중인 대기열을 사용하여 모든 스레드에 자살 요청을 보냅니다. –

2

한 가지 방법은 직접 os._exit(signal.SIGTERM)를 호출 SIGTERM위한 신호 처리기를 설치하는 것입니다. 그러나 옵션 인 timeoutQueue.get에 지정하지 않으면 get 메서드가 반환 될 때까지 신호 처리기 함수가 실행되지 않습니다. (그건 완전히 문서화되지 않았으므로, 독자적으로 발견했습니다.) 따라서 sys.maxint을 시간 초과로 지정하고 Queue.get 호출을 순회를 위해 재 시도 루프에 넣을 수 있습니다.

+2

예,'Queue.get'에'timeout = sys.maxint'를 지정해야하는 것은 입니다. –

0

대기열에서 작업 시간 초과를 설정하지 않는 이유는 무엇입니까? 그런 다음 스레드는 이벤트 발생 여부를 확인하여 마무리해야하는지 정기적으로 확인할 수 있습니다.

-1

KeyboardInterrupt의 큐를 비우고 스레드가 정상적으로 종료되도록하여 문제를 해결할 수있었습니다.

이 문제를 해결하는 가장 좋은 방법인지는 모르겠지만 간단하고 매우 깨끗합니다. 당신이 다른 스레드가 정상적으로 종료시키는에 관심이없는 경우

targets = Queue.Queue() 
threads_num = 10 
threads = [] 

for i in threads_num: 
    t = MyThread() 
    t.setDaemon(True) 
    threads.append(t) 
    t.start() 

while True: 
    try: 
     # If the queue is empty exit loop 
     if self.targets.empty() is True: 
      break 

    # KeyboardInterrupt handler 
    except KeyboardInterrupt: 
     print "[X] Interrupt! Killing threads..." 
     # Substitute the old queue with a new empty one and exit loop 
     targets = Queue.Queue() 
     break 

# Join every thread on the queue normally 
targets.join() 
+0

문서에서는 안전하게 대기열에서 .empty()를 사용할 수 없다고 말합니다. – zindel

+0

@zindel 예 힘든 길을 발견했습니다. – gbr

5

, 단순히 데몬 모드를 시작하고 종료 스레드에서 큐의 조인 포장.

그런 식으로 대기열의 join 메소드를 기다릴 필요없이 시간 제한을 지원하고 예외를 차단하지 않는 스레드의 join 메소드를 사용할 수 있습니다. 즉

이 같은 것을 할 :

term = Thread(target=someQueueVar.join) 
term.daemon = True 
term.start() 
while (term.isAlive()): 
    term.join(3600) 

지금, Ctrl + C는 파이썬 인터프리터을 분취 MainThread 종료 모든 스레드가 "데몬"로 표시된 하드를-죽인다. 이것은 다른 모든 스레드에 대해 "Thread.daemon"을 설정하거나 올바른 예외 (KeyboardInterrupt 또는 SystemExit)를 catch하고 종료하기 위해 수행해야 할 모든 작업을 수행하여 정상적으로 종료해야 함을 의미합니다.

또한 term.join()으로 숫자를 전달하려면 반드시이 필요합니다. 그렇지 않으면 모든 예외가 무시되므로 유의하십시오.그래도 임의로 높은 숫자를 선택할 수 있습니다.

관련 문제