1

我用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,所以线程应该自动完成。但事实并非如此。那么制作人具体在哪里呢?发生异常时如何使其停止?

4

1 回答 1

2

ThreadManagershutdown没有正确同步;它基本上是一个threading.active_count() > 1永远不会退出的while循环。如果两个或更多线程最终在此方法中,它们(和程序)将永远不会退出。

与其不断调用随机线程(甚至可能与您的线程无关),只需在 ThreadManager 中保存所有已启动线程的清单,然后stop对它们中的每一个调用一次。此外,实际调用 stop 的代码应该移到它在逻辑上所属的 ThreadManager 中。

此外,ThreadManager.getInstance它不是线程安全的;您最终可能会得到多个 ThreadManager。你应该使用

总而言之,看起来您正在重新实现一个ThreadPoolExecutor. 你为什么不使用它呢?

于 2012-12-05T12:31:42.963 回答