Python:スレッドから呼び出された `sys.exit(msg)`が `msg`をstderrに出力しないのはなぜですか?
-
05-07-2019 - |
質問
今日は、子スレッドから呼び出された sys.exit()
がメインプロセスを強制終了しないという事実に反しました。私はこれを前に知りませんでした、そして、これは大丈夫ですが、私はこれを実現するために長い時間が必要でした。 sys.exit(msg)
が msg
を stderr
に出力した場合、多くの時間を節約できたでしょう。しかし、そうではなかった。
これは私のアプリケーションの本当のバグではないことが判明しました。それは sys.exit(msg)
を呼び出し、意図的な意味で意味のあるエラーが発生しました-しかし、私はこれを見ることができませんでした。
sys.exit()
のドキュメント記載されている:
" [...]他のオブジェクトはすべて sys.stderr
に出力され、終了コード1"
これは、 sys.exit()
が明らかに thread.exit()
:
" SystemExit例外を発生させます。キャッチされない場合、これによりスレッドはサイレント"
プログラマが sys.exit(msg)
にエラーメッセージを出力させたい場合は、呼び出し元の場所に関係なく、これを出力する必要があります。何故なの?現在のところ、理由はわかりません。少なくとも sys.exit()
のドキュメントには、メッセージがスレッドから出力されないというヒントが必要です。
あなたはどう思いますか?エラーメッセージがスレッドから隠されるのはなぜですか?これは理にかなっていますか?
よろしく、
Jan-Philip Gehrcke
解決
メイン以外のスレッドによって呼び出された場合のsys.exitおよびSystemExitに関して、Pythonドキュメントが間違っているか、より正確には不完全であることに同意します。 Pythonオンライントラッカーでドキュメントの問題を開いて、今後のドキュメントの反復で対処できるようにしてください(おそらく近い将来-ドキュメントの修正はコードの修正よりも簡単でスムーズです;-)。
救済策はもちろん非常に簡単です- trying
を行うデコレータで threading.Thread
のターゲットとして使用している関数をラップするだけです/ SystemExit、e:
を除き、「標準エラー出力への書き込み」を実行します。終了する前に、必要な追加機能(または、おそらく、代わりにlogging.error呼び出しを使用します)。しかし、あなたが正しく指摘しているドキュメントの問題では、問題に遭遇し、実際にそれを特定するためにデバッグにある程度の時間を費やさなければならない限り、それを行うことを考えるのは難しいです実行します(コアPython開発者の集合的な代理として-申し訳ありません!)。
他のヒント
Pythonのすべてのスレッドが等しいわけではありません。スレッドからsys.exitを呼び出しても、実際にはシステムは終了しません。したがって、子スレッドからsys.exit()を呼び出すことは無意味なので、期待どおりに動作しないことは理にかなっています。
このページでは、オブジェクトのスレッド化、およびスレッドと特別な「メイン」スレッド。