2012-12-05 70 views
1

我在python中编写了一个小线程示例。我面临的问题是,当线程内有异常时,该线程继续运行,并且不会退出。我有下面的代码:线程不退出python

class Producer (threading.Thread): 

    def __init__(self, threadId): 
     threading.Thread.__init__(self) 
     self.threadId = threadId 
     self.killReceived = False 

    def produce(self): 
     while 1: 
      if self.killReceived == True: 
       print self.threadId+"inside kill section" 
       return False 
      print "running" 
      time.sleep(1) 
      raise Exception('boo') 

    def run(self): 
     try: 
      self.produce() 
     except Exception as e: 
      ThreadManager.getInstance().shutdown(self.threadId) 

    def stop(self): 
     self.killReceived = True 

class ThreadManager: 
    _instance = None 

    @staticmethod 
    def getInstance(): 
     if ThreadManager._instance == None: 
      ThreadManager._instance = ThreadManager() 
     return ThreadManager._instance 

    def __init__(self): 
     ''' some initializations ''' 

    def shutdown(self, threadId): 
     while threading.active_count() > 1: 
      for thread in threading.enumerate():  
       if type(thread) != threading._MainThread: #never kill main thread directly 
        thread.stop() 
        #print thread.threadId+" is alive? "+str(thread.isAlive()) 

当我引发异常内生产它被抓住,我火ThreadManager,进而调用除主线程运行的所有线程的stop()方法的关机方法。消费者使用这种策略退出,但生产者挂起。如果我运行isAlive方法,我发现生产者线程仍在运行,但它的运行方法不再运行。因为它不再打印running。作为在run()内部的produce方法的异常冒泡,所以线程应该自动完成。但事实并非如此。那么制作人究竟在哪里呢?发生某种异常时如何停止?

回答

2

ThreadManager的shutdown未正确同步;它基本上是一段不会退出的循环。如果两个或多个线程以此方法结束,它们(和程序)将永远不会退出。

而不是连续调用随机线程(甚至可能与您的线程无关),只需保留ThreadManager中所有已启动线程的清单,然后每个调用stop一次。另外,实际调用stop的代码应该移入ThreadManager,它在逻辑上属于它。

此外,ThreadManager.getInstance不是线程安全的;您可能会因为现状而结束多个线程管理器。你应该使用lock

总之,它看起来像你正在重新实现ThreadPoolExecutor。你为什么不使用它呢?

+0

是的,你是正确的循环的事情。通话永远不会结束,所以制作人似乎永远不会退出ThreadPoolExecutor,这是一个很好的建议,我会研究它。感谢您指导我。 58K积分!!!(敬礼) – Shades88