线程不退出python

线程不退出python,python,multithreading,Python,Multithreading,我用python编写了一个小线程示例。我面临的问题是,当线程内部出现异常时,该线程会继续运行,并且不会退出。我有以下代码: class Producer (threading.Thread): def __init__(self, threadId): threading.Thread.__init__(self) self.threadId = threadId self.killReceived = False def p

我用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())

当我在producer内部引发异常时,它会被捕获,并触发ThreadManager的shutdown方法,该方法反过来调用除主线程之外的所有运行线程的stop()方法。消费者使用此策略退出,但生产者挂起。如果我运行
isAlive
方法,我会看到生产者线程仍在运行,但它的run方法不再运行。因为它不再打印运行中的
。当异常从
冒泡出来时,会生成run()中的
方法,所以线程应该自动完成。但事实并非如此。那么制作人到底在哪里?当出现异常时,如何使其停止?

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

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

另外,
ThreadManager.getInstance
不是线程安全的;最终可能会出现多个线程管理器。你应该使用一个


总而言之,看起来你正在重新实现一个新的目标。你为什么不用它来代替呢?

是的,你对这个循环的看法是正确的。通话从未结束,所以制作人似乎从未退出。ThreadPoolExecutor,这是一个很好的建议,我会研究一下。谢谢你指导我。58K分!!!(敬礼)