Skip to main content
 首页 » 编程设计

当其中一个线程中存在未捕获的异常时,Python多线程程序不会退出

2024年09月03日31虾米姐

下面的代码生成 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()