2012-12-05 74 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