呼び出し元スレッドでスレッドの例外をキャッチしますか? 質問する

呼び出し元スレッドでスレッドの例外をキャッチしますか? 質問する

私は 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

ベストアンサー1

問題は、それがthread_obj.start()すぐに返されることです。生成した子スレッドは、独自のコンテキストで独自のスタックを使用して実行されます。そこで発生する例外はすべて、子スレッドのコンテキストで、独自のスタック内にあります。この情報を親スレッドに伝えるために今思いつく方法の 1 つは、何らかのメッセージ パッシングを使用することです。これについて調べてみるといいかもしれません。

これを試着してサイズを確認してください:

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

おすすめ記事