呼び出し側スレッドでスレッドの例外をキャッチする
Python では、マルチスレッド プログラミングでは、子スレッドで発生する例外を処理する際に課題が生じます。子スレッドで例外が発生すると、例外はそのスレッドに限定されるため、呼び出し元のスレッドが例外をキャプチャして処理することが困難になります。
中心的な問題と根拠
主な問題は、thread_obj.start() メソッドの即時性にあります。このメソッドは、独自のコンテキストおよびスタックで子スレッドの実行を開始します。その結果、子スレッド内で発生した例外は呼び出し元のスレッドに伝播されません。
問題の解決
この問題に対処するには、次のような効果的な手法を使用します。メッセージパッシング。このアプローチでは、子スレッドと呼び出し元スレッドの間に通信チャネルが確立され、子スレッドが例外情報を親に伝達できるようになります。
実装
以下は子スレッドの例外をキャプチャして呼び出し元に表示する方法を示す例thread:
import sys import threading import queue class ExcThread(threading.Thread): def __init__(self, bucket): threading.Thread.__init__(self) self.bucket = bucket def run(self): try: raise Exception('An error occured here.') except Exception: self.bucket.put(sys.exc_info()) def main(): bucket = queue.Queue() thread_obj = ExcThread(bucket) thread_obj.start() while True: try: exc = bucket.get(block=False) except queue.Empty: pass else: exc_type, exc_obj, exc_trace = exc # deal with the exception print exc_type, exc_obj print exc_trace thread_obj.join(0.1) if thread_obj.isAlive(): continue else: break if __name__ == '__main__': main()
説明
この例では、ExcThread クラスが例外の生成を担当する子スレッドとして機能します。 main() 関数は呼び出し側スレッドとして機能します。通信チャネルは、queue.Queue() オブジェクト (コードではバケットと呼ばれます) を使用して確立されます。
ExcThread の run() メソッド内で、発生した例外はすべてバケットに配置されます。呼び出し側スレッドは、ループ内でバケットを継続的にチェックします。バケット内で例外が利用可能な場合、それが取得され、例外の詳細 (タイプ、オブジェクト、およびトレースバック) が出力されます。
このアプローチは、子スレッドと呼び出し側スレッドの間の通信ギャップを効果的に橋渡しします。これにより、後者が前者で生成された例外をキャッチして処理できるようになります。
以上がPython で子スレッドで発生した例外をキャッチするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。