1. ホーム
  2. パイソン

[解決済み】スレッドの例外を呼び出し側のスレッドでキャッチする?

2022-04-04 07:35:54

質問

私はPythonと一般的なマルチスレッドプログラミングの非常に新しい人です。 基本的に、私はファイルを別の場所にコピーするスクリプトを持っています。 私はこれを別のスレッドに配置し、以下を出力できるようにしたいと思います。 .... を使用して、スクリプトがまだ実行中であることを示します。

問題は、ファイルをコピーできない場合、例外が発生することです。 メインスレッドで実行している場合は問題ないのですが、以下のようなコードではうまくいきません。

try:
    threadClass = TheThread(param1, param2, etc.)
    threadClass.start()   ##### **Exception takes place here**
except:
    print "Caught an exception"

スレッドクラス自体で、例外を再スローしようとしましたが、うまくいきません。 ここで同じような質問をしている人を見ましたが、みんな私がやろうとしていることよりもっと具体的なことをしているようです(そして提示された解決策をよく理解していないのです)。私は、人々が sys.exc_info() しかし、どこで、どのように使用すればよいのかわかりません。

編集する スレッドクラスのコードは以下の通りです。

class TheThread(threading.Thread):
    def __init__(self, sourceFolder, destFolder):
        threading.Thread.__init__(self)
        self.sourceFolder = sourceFolder
        self.destFolder = destFolder
    
    def run(self):
        try:
           shul.copytree(self.sourceFolder, self.destFolder)
        except:
           raise

解決方法は?

問題は thread_obj.start() はすぐに返します。生成した子スレッドは自分のコンテキストで実行され、自分のスタックを持っています。そこで発生した例外はすべて子スレッドのコンテキストにあり、子スレッド自身のスタックにある。この情報を親スレッドに伝える方法として今思いつくのは、ある種のメッセージパッシングを使用することです。

試しに着てみてください。

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()