1

重複の可能性:
Pythonの呼び出し元スレッドでスレッドの例外をキャッチします

私は与えられたコードを持っていて、

thread.start_new_thread()

python docで読んだように、「関数が未処理の例外で終了すると、スタックトレースが出力され、スレッドが終了します(ただし、他のスレッドは引き続き実行されます)。」しかし、(新しい)関数が例外で終了したときにメインスレッドも終了したいので、例外はメインスレッドに転送されます。これどうやってするの?

編集:ここに私のコードの一部があります:

def CaptureRegionAsync(region=SCREEN, name="Region", asyncDelay=None, subDir="de"):
    if asyncDelay is None:
        CaptureRegion(region, name, subDir)
    else:
        thread.start_new_thread(_CaptureRegionAsync, (region, name, asyncDelay, subDir))

def _CaptureRegionAsync(region, name, asyncDelay, subDir):
    time.sleep(max(0, asyncDelay))
    CaptureRegion(region, name, subDir)

def CaptureRegion(region=SCREEN, name="Region", subDir="de"):
    ...
    if found:
        return
    else:
        raise Exception(u"[warn] Screenshot has changed: %s" % filename)

CaptureRegionAsync(myregion,"name",2)
4

1 に答える 1

0

UPD:あなたの質問は私が思っていたものとは異なるため、これは最善の解決策ではありません。変更できないスレッドコードの例外に対処しようとしていると思いました。しかし、私は答えを削除しないことにしました。

別のスレッドからの例外をキャッチするのは難しいです。通常は手動で転送する必要があります。

スレッド関数をラップできますか?exceptクラッシュするワーカースレッドをtry...exceptにラップすると、メインスレッドをブロックで終了するために必要なアクションを実行できます(sys.exit私には驚きですが、役に立たないようですが、何かが必要な場合もありますthread.interrupt_main()os.abort()メインスレッドが定期的にチェックしているフラグを設定するなど、より優雅です)。

ただし、関数をラップできない場合(サードパーティのコード呼び出しを変更できない場合start_new_thread)は、スレッドモジュール(またはサードパーティモジュール自体)にモンキーパッチを適用してみてください。のパッチを適用したバージョンはstart_new_thread()、心配している関数をラップする必要があります。

import thread
import sys
import time

def t():
    print "Thread started"
    raise Exception("t Kaboom")

def t1():
    print "Thread started"
    raise Exception("t1 Kaboom")


def decorate(s_n_t):
    def decorated(f, a, kw={}):
        if f != t:
            return s_n_t(f, a, kw)
        def thunk(*args, **kwargs):
            try:
                f(*args, **kwargs)
            except:
                print "Kaboom"
                thread.interrupt_main() # or os.abort()
        return s_n_t(thunk, a, kw)
    return decorated

# Now let's do monkey patching:
thread.start_new_thread = decorate(thread.start_new_thread)

thread.start_new_thread(t1, ())
time.sleep(5)
thread.start_new_thread(t, ())
time.sleep(5)

t()ここでは、 causes thread.interrupt_main()/の例外がありos.abort()ます。アプリケーションの他のスレッド機能は影響を受けません。

于 2013-01-14T10:11:47.843 に答える