python - 当其中一个线程中存在未捕获的异常时,Python 多线程程序不会退出
问题描述
下面的代码产生 100 个线程并随机生成一个异常。即使所有线程都已执行完毕(虽然有些线程会产生异常),但主程序仍然没有退出。难道我做错了什么?需要修改什么,以便如果其中一个线程发生异常,主线程仍然退出?
from __future__ import print_function
from threading import Thread
import sys
import random
from queue import Queue
__author__ = 'aanush'
"""
Testing if threading exits the python script gracefully
"""
class NoException(Exception):
pass
class ThreadFail(Thread):
"""
Class which helps us in doing multi-threading which improves performance of the script
"""
def __init__(self, name, counter, queue_):
Thread.__init__(self)
self.queue = queue_
self.threadID = counter
self.name = name
self.counter = counter
def run(self):
while True:
# Expand the tuple from queue and pass it to the target function
some_random_num = self.queue.get()
func_test(some_random_num)
self.queue.task_done()
def func_test(random_num):
if random_num <= 10:
print("Sleep time - {} greater than 10. Not raising exception".format(random_num))
else:
print('sleep time less than 10 : Raising exception')
raise NoException
queue = Queue()
for thread_num in range(100):
worker = ThreadFail('Thread-{}'.format(thread_num), thread_num, queue)
worker.daemon = True
worker.start()
for x in range(1000):
queue.put(random.randrange(1, 15))
queue.join()
解决方案
您在这里遇到了僵局。由于异常而终止的线程不会释放共享资源上的持有锁,因此queue
会损坏。您需要捕获线程内的异常并让它们优雅地退出。
def run(self):
while True:
# Expand the tuple from queue and pass it to the target function
some_random_num = self.queue.get()
try:
func_test(some_random_num)
except NoException:
pass
finally:
self.queue.task_done()
推荐阅读
- gravityforms - 这是什么意思“尝试访问类型为 null 的值的数组偏移量”在 plugins/gravityforms/form_display.php
- mysql - 我需要了解如何防止 NodeJS 上的 sql 注入 sequelize ORM
- sql - 从 AdventureWorks 数据库中选择随机数据集
- ios - 实时流媒体方法,以避免观众端的延迟
- javascript - 同步承诺链
- r - 如何识别多个独立的子图并将其对应的子图分配给R中的每个节点?
- typescript - 是否有必要在所有组件中导入 vue?Nuxt 和打字稿
- java - WAS 8.5.5 ejb 查找产生无效的对象引用 com.ibm.ws.naming.util.InvalidObjectException
- python-3.9 - 如何编写python脚本以在预定时间内弹出通知?
- c - remove() 函数在 C 语言中是如何工作的?