【问题标题】:thread not exiting python线程不退出python
【发布时间】:2012-12-05 20:31:42
【问题描述】:

我用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。由于run() 内部的produce 方法中出现异常,所以线程应该自动完成。但事实并非如此。那么制作人具体在哪里呢?发生异常时如何让它停止?

【问题讨论】:

    标签: python multithreading


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 是的,你对那个循环的事情是正确的。通话永远不会结束,因此生产者似乎永远不会退出。 ThreadPoolExecutor,这是一个很好的建议,我会研究一下。谢谢你指导我。 58K点!!!(敬礼)
    猜你喜欢
    • 2014-03-17
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    • 2012-04-25
    相关资源
    最近更新 更多