我在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()内部,所以线程应该自动完成。但事实并非如此。那么制作人究竟在哪里?如果出现异常,我怎么能让它停止?
答案 0 :(得分:2)
ThreadManager的shutdown
未正确同步;它基本上是一个永不退出的threading.active_count() > 1
循环。如果两个或多个线程在此方法中结束,则它们(和程序)将永远不会退出。
不要连续调用随机线程(甚至可能与你的线程无关),只需在ThreadManager中保留所有已启动线程的清单,并调用每个线程的stop
一次。此外,实际调用stop的代码应该移动到它在逻辑上属于的ThreadManager中。
此外,ThreadManager.getInstance
不是线程安全的;您最终可能会拥有多个ThreadManagers。您应该使用lock。
总而言之,您似乎正在重新实现ThreadPoolExecutor
。你为什么不用它呢?