Вызвать необработанные исключения в потоке основного потока?[дубликат]

StackOverflow https://stackoverflow.com/questions/1854216

Вопрос

На этот вопрос уже есть ответ здесь:

Есть несколько подобных вопросов, но ни один из них не дает ответа, который мне нужен.

Если я создаю темы через threading.Thread, которые затем выдают необработанные исключения, эти потоки завершаются.Я хочу сохранить распечатку сведений об исключении по умолчанию с трассировкой стека, но также отключить весь процесс.

Я подумал, что можно было бы перехватить все исключения в потоках и повторно вызвать их в объекте основного потока, или, возможно, можно вручную выполнить обработку исключений по умолчанию, а затем вызвать SystemExit в основной теме.

Как лучше всего это сделать?

Это было полезно?

Решение

Я написал о Повторное создание исключений в Python, включая что-то очень похожее на это в качестве примера.

В рабочем потоке вы делаете это (Python 2.x, версию Python 3.x см. ниже):

try:
    self.result = self.do_something_dangerous()
except Exception, e:
    import sys
    self.exc_info = sys.exc_info()

и в основном потоке вы делаете это:

if self.exc_info:
    raise self.exc_info[1], None, self.exc_info[2]
return self.result

Исключение появится в основном потоке так же, как если бы оно было создано в рабочем потоке.

Питон 3.x:

try:
    self.result = self.do_something_dangerous()
except Exception as e:
    import sys
    self.exc_info = sys.exc_info()

и в вашей основной теме:

if self.exc_info:
    raise self.exc_info[1].with_traceback(self.exc_info[2])
return self.result

Другие советы

Единственное исключение, которое вторичный поток может надежно вызвать в основном потоке, — это KeyboardInterrupt:вторичный поток делает это путем вызова функции thread.interrupt_main().Невозможно связать дополнительную информацию (о причине исключения) с вызываемым объектом исключения — последний всегда представляет собой простое сообщение. KeyboardInterrupt.Итак, вам нужно спрятать эту информацию где-нибудь еще, например.на выделенном экземпляре Очередь.Очередь -- эта информация может включать в себя результаты, которые может получить вторичный поток sys.exc_info(), и, конечно же, все, что вы найдете полезным.

Основной поток должен будет восстановить эту дополнительную информацию (и принять во внимание, что очередь будет пустой, если прерывание клавиатуры на самом деле произошло из-за того, что пользователь нажал Control-C или что-то подобное, поэтому используйте get_nowait и будьте готовы иметь дело с Queue.Empty исключение, например), отформатируйте его по своему усмотрению и завершите (если все вторичные потоки демонs, весь процесс завершается при завершении основного потока).

К сожалению, принятый ответ не отвечает на вопрос.Вы предпочитаете передавать сведения об исключении в очередь.Пожалуйста, посмотрите: Перехват исключения потока в вызывающем потоке в Python

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top