Как перехватывать исключения из нескольких потоков?

#python #python-3.x #multithreading #exception #python-multithreading

#python #python-3.x #многопоточность #исключение #python-многопоточность

Вопрос:

У меня есть набор функций, которые я хотел бы выполнить в потоках. Некоторые из этих функций могут вызывать конкретное исключение, которое я хотел бы перехватить, отдельно для каждого потока.

Я попробовал что-то вроде

 import threading

class MyException(Exception):
    pass

def fun():
    raise MyException

myfuns = [threading.Thread(target=fun), threading.Thread(target=fun)]
for myfun in myfuns:
    try:
        myfun.start()
    except MyException:
        print("caught MyException")
 

Я ожидал увидеть caught MyException дважды, по одному для каждого потока. Но есть только один.

Возможно ли перехватывать исключения в потоках независимо друг от друга? (другими словами: когда поток создает исключение, управляйте им в коде, который вызвал поток?)

Комментарии:

1. Какая версия Python?

2. @Woj: Достаточно ли threading.excepthook ?

3. Достаточно ли вы продвинулись в разработке / реализации, чтобы провести рефакторинг с помощью concurrent.futures?

4. @wwii: Python 3.8. Я на стадии разработки. Мой текущий (любительский / домашний) код вызывает функции последовательно, и я хотел бы использовать их. Я не знаю concurrent.futures, поэтому я прочитаю документы, чтобы понять, как это может помочь

5. @MauriceMeyer: это может быть очень интересным решением — я прочитаю подробности и попробую это, спасибо.

Ответ №1:

Для Python 3.8 вы можете определить обработчик для неперехваченных исключений.

 import threading

def f(args):
    print(f'caught {args.exc_type} with value {args.exc_value} in thread {args.thread}n')
    
threading.excepthook = f

class MyException(Exception):
    pass

def fun():
    raise MyException

myfuns = [threading.Thread(target=fun), threading.Thread(target=fun)]
for myfun in myfuns:
    myfun.start()
for myfun in myfuns:
    myfun.join()
 

Комментарии:

1. Спасибо — похоже, что в вашем другом предложении в concurrent.futures качестве примера приведена моя точная проблема: docs.python.org/3/library /…