线程没有退出python

时间:2012-12-05 11:25:10

标签: python multithreading

我在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方法,我看到生产者线程仍在运行,但是它的run方法不再运行。因为它不再打印running。由于produce方法中的异常气泡在run()内部,所以线程应该自动完成。但事实并非如此。那么制作人究竟在哪里?如果出现异常,我怎么能让它停止?

1 个答案:

答案 0 :(得分:2)

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

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

此外,ThreadManager.getInstance不是线程安全的;您最终可能会拥有多个ThreadManagers。您应该使用lock

总而言之,您似乎正在重新实现ThreadPoolExecutor。你为什么不用它呢?