2009-12-06 4 views
12

似たような質問がありますが、私が必要とする回答はありません。メインスレッドのスレッドで未処理の例外を発生させますか?

threading.Threadでスレッドを作成して、処理されない例外をスローすると、それらのスレッドは終了します。私は、スタックトレースで例外の詳細をデフォルトのままにしておきたいが、プロセス全体を停止させたい。

私は、スレッド内のすべての例外を捕捉してメインスレッドオブジェクト上でそれらを呼び出すことが可能かもしれないと考えました。または、手動でデフォルトの例外処理を手動で実行してから、メインにSystemExit糸。

これについてはどのような方法が最適ですか?

答えて

15

私は約Re-throwing exceptions in Pythonと書いています。これは例として非常によく似ています。

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

をし、あなたのメインスレッド上で、あなたがこれを行う:あなたのワーカースレッドで

あなたがこれを行う(Pythonの2.xのを、Pythonの3.xバージョンについては下記を参照)

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

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

のPython 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 
+0

メインスレッドに 'thrdobj.exc_info'をスローするのではなく、なぜあなたが転覆したときに例外タイプを削除するのですか? –

+0

私は今、3arg raise文を読まなければなりませんでした。 「自己」についての質問はまだまだ立っています、良い答えをありがとう、私はそれを試してみます –

+0

私は自己についてのあなたの質問は何か分かりません。このコードは、ワーカースレッド上で作業を延期するために使用されるオブジェクトから来ているため、同じオブジェクトはワーカースレッドとメインスレッドでコードを実行します。 –

9

セカンダリスレッドが確実にメインスレッドに上げることができる唯一の例外はKeyboardInterruptです:ところで2次スレッドは、関数thread.interrupt_main()を呼び出すことによって行われます。余分な情報(例外の理由について)を発生させる例外オブジェクトに関連付ける方法はありません。後者は常に単なるKeyboardInterruptです。その情報をどこか他の場所に隠しておく必要があります。 Queue.Queueの専用インスタンスには、その情報には、セカンダリスレッドがsys.exc_info()を経由して取得できる結果などが含まれています。

メインスレッドはその余分な情報を回復する必要があります(そしてキーボード割り込みが実際にコントロールCなどを打つユーザのためにキューが空であることを考慮に入れるので、get_nowaitを使用して準備完了ですたとえば、Queue.Emptyの例外を処理するため)、必要なときにフォーマットして終了します(すべてのセカンダリスレッドがdaemonの場合、メインスレッドが終了するとプロセス全体が終了します)。

+0

更新されたスレッドドキュメントのリンク:https://docs.python.org/3.6/library/_thread.html?highlight=interrupt_main#_thread.interrupt_main – user2682863

関連する問題