16

同様の質問がいくつかありますが、私が必要とする答えを提供するものはありません。

を介してスレッドを作成するthreading.Threadと、未処理の例外がスローされ、それらのスレッドは終了します。スタック トレースで例外の詳細のデフォルトの出力を保持したいのですが、プロセス全体も停止します。

スレッド内のすべての例外をキャッチして、メイン スレッド オブジェクトでそれらを再発生させるか、デフォルトの例外処理を手動で実行してからメイン スレッドで a を発生させることが可能かもしれないと考えましたSystemExit

これについて最善の方法は何ですか?

4

3 に答える 3

18

例として、これに非常によく似たものを含め、 Python で例外を再スローする について書きました。

ワーカー スレッドでこれを行います (Python 3.x、Python 2.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

Python 2.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

ワーカー スレッドで例外が発生したかのように、例外がメイン スレッドに表示されます。

于 2009-12-06T03:39:43.267 に答える
12

セカンダリ スレッドがメイン スレッドで確実に発生できる唯一の例外は、次のKeyboardInterruptとおりです。セカンダリ スレッドがそれを行う方法は、関数を呼び出すことですthread.interrupt_main()。(例外の理由に関する) 追加情報を、発生する例外オブジェクトに関連付ける方法はありません。後者は常に単純なKeyboardInterrupt. そのため、その情報を別の場所、たとえばQueue.Queueの専用インスタンスなどに隠しておく必要があります。その情報には、セカンダリ スレッドが 経由sys.exc_info()で取得できる結果や、もちろん役立つその他の情報が含まれる場合があります。

メインスレッドはその余分な情報を回復する必要があります(そして、キーボード割り込みが実際にユーザーがコントロールCなどを押したことが原因である場合、キューが空になることを考慮してください。したがって、使用して例外get_nowaitに対処する準備をしてくださいQueue.Empty、たとえば)、必要に応じてフォーマットし、終了します(すべてのセカンダリスレッドがデーモンの場合、メインスレッドが終了するとプロセス全体が終了します)。

于 2009-12-06T19:39:40.170 に答える
5

残念ながら、受け入れられた回答は質問に答えていません。例外の詳細をキューにパイプすることをお勧めします。ご覧ください: Catch a thread's exception in the caller thread in Python

于 2015-04-05T09:14:38.030 に答える