2013-04-14 2 views
0

일반적인 예외 처리기로 파이썬 응용 프로그램의 모든 스레드에 대한 예외를 catch 할 수 있습니까?멀티 스레드 파이썬 응용 프로그램의 공통 예외 처리기

다음 예제를 고려하십시오. 나는 주 스레드에서 CTRL+C을 잡아 내고 싶지만 때로는 다른 스레드를 종료하지 않는 작업자 스레드 중 하나에 의해 잡힐 수 있습니다. 이 경우의 출력은 다음과 같습니다.

^CTraceback (most recent call last): 
    File "thread-example.py", line 50, in <module> 
    main() 
    File "thread-example.py", line 30, in main 
    t.join(1) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 675, in join 
    self.__block.wait(delay) 
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 263, in wait 
    _sleep(delay) 
KeyboardInterrupt 

이것은 테스트 응용 프로그램입니다.

#!/usr/bin/python 

import os 
import sys 
import threading 
import time 
import subprocess 
import signal 


class Worker(threading.Thread): 
    def __init__(self, name): 
     threading.Thread.__init__(self) 
     self.kill_received = False 
     self.daemon = True 
     self.name = name 

    def run(self): 
     while not self.kill_received: 
      time.sleep(1) 
      print self.name 

def main(): 
    threads = [] 

    for i in xrange(10): 
     t = Worker('worker-%d' % i) 
     threads.append(t) 
     t.start() 
     t.join(1) 

    while len(threads) > 0: 
     try: 
      threads = [t for t in threads if t is not None and t.isAlive()] 
      time.sleep(1) 
     except KeyboardInterrupt: 
      print "Ctrl-c received! Sending kill to threads..." 
      for t in threads: 
       t.kill_received = True 
      # wait for threads to finish gracefully, then kill them anyway. 
      # since all threads are daemons, they should finish once the main 
      # loop terminates 
      for i in xrange(5): 
       print '%i ...' % (5-i) 
       time.sleep(1) 
      print 'Exit!' 
      os._exit(1) 

if __name__ == '__main__': 
    main() 
+0

일반적인 스레드 간 통신 기술을 사용할 때는 예외를 전달해야합니다. 예제는 [Python의 호출자 스레드에서 스레드의 예외 잡기] (http://stackoverflow.com/q/2829329)를 참조하십시오. –

답변

1

Ctrl-C 자체가 예외는 아니며 신호입니다. 다음과 같이 "메인"이외의 모든 생성 된 스레드를 무시하도록 설정하십시오.

import signal 
signal.signal(signal.SIGINT, signal.SIG_IGN) 
+0

POSIX 시스템 용입니까? 그 외에도 다른 스레드로 전달되지 못하도록 신호를 기다리는 방법이 없었습니까? –

+0

Windows, Mac OS 및 Linux에서이 작업이 필요합니다. – orange

+0

Windows에서 작동하는지 여부는 알 수 없습니다. 시도 해봐. :) 특별히'signalfd'를 사용하여 신호를 기다릴 수는 있지만, 파이썬이나이 특별한 경우를 원할 것입니다. –

관련 문제