2013-04-14 55 views
0

是否有可能使用通用異常處理程序捕獲Python應用程序的所有線程的異常?多線程Python應用程序的常見異常處理程序

考慮下面的例子。我想從主線程中捕獲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'專門等待信號,但是我懷疑你想用Python還是在這種特殊情況下。 –