8

新しいスレッドを生成した親に、生成されたスレッドの例外をキャッチさせる方法はありますか?以下は、私が達成しようとしていることの実際の基本的な例です。例外が発生するとカウントを停止するはずですが、キャッチする方法がわかりません。例外はスレッドセーフですか?モジュールを使用できるようにしたいとSubprocess思いますが、Python 2.3の使用に固執しており、他にこれを行う方法がわかりません。おそらくthreadingモジュールを使用していますか?

import time
import thread

def test(): 
    try:
        test = thread.start_new_thread(watchdog, (5,))
        count(10)
    except:
        print('Stopped Counting')

def count(num):
    for i in range(num):
        print i
        time.sleep(1)

def watchdog(timeout):
    time.sleep(timeout)
    raise Exception('Ran out of time')

if __name__ == '__main__':
    test()

アップデート

私の元のコードは少し誤解を招くものでした。それは本当にこのようなものを探しています:

import time
import thread
import os

def test(): 
    try:
        test = thread.start_new_thread(watchdog, (5,))
        os.system('count_to_10.exe')
    except:
        print('Stopped Counting')

def watchdog(timeout):
    time.sleep(timeout)
    raise Exception('Ran out of time')

if __name__ == '__main__':
    test()

プログラムが何らかの理由でハングアップした場合にos.system呼び出しを強制終了するウォッチドッグを作成しようとしています。

4

4 に答える 4

3

どうしてこんなものじゃないの?

def test(): 
    def exeption_cb():
        os._exit()
    test = thread.start_new_thread(watchdog, (5, exception_cb))
    os.system('count_to_10.exe')
    print('Stopped Counting')

def watchdog(timeout, callback):
    time.sleep(timeout)
    callback()

これにより、プロセス全体が停止します。別のスレッドでos.systemを起動し、カウントダウンしてからそのスレッドを強制終了することもできます。このようなもの、

def system_call():
    os.system('count_to_10.exe')

system_thread = thread.start_new_thread(system_call)
time.sleep(timeout)
system_thread.kill()
于 2011-08-07T18:14:58.327 に答える
2

あなたが本当にやろうとしているのが例外の受け渡し/処理である場合、親プロセスは子プロセスによって生成されたステータスコード(および出力)しか「見る」ことができないため、サブプロセスを使用したくないと思います-子プロセスで即時かつ壊滅的な障害が発生した場合にのみ、親で例外が「再発生」します:http: //docs.python.org/library/subprocess.html#exceptions

そして(例外を渡そうとしている場合も)スレッドが必要かどうかもわかりません。結局のところ、例外の要点(IMO)は、「呼び出し元によって」(tryブロック内で)処理できるもの、または処理されない場合に意味のあるバックトレース情報(呼び出しシーケンス)を提供できるものを持つことです。どちらのアイデアも、あるスレッドで「スロー」し、別のスレッドで「キャッチ」する場合には実際には機能しません。

あるロジックを別のロジックで「タイムアウト」させることが本当の目標である場合、「ウォッチドッグ」を別のプロセス、つまり「子」からの出力を監視する「親」にすることは理にかなっていると思います。経過時間と同様に)、または監視対象のプロセス(およびクロック)によるログ行やDBの更新などを「監視」する「ピア」。どちらの場合も、特に関連する例外はありません。そして、この質問に対するAlexMartelliの回答を確認することをお勧めします。タイムアウト付きのモジュール「サブプロセス」の使用

この質問には、あなたの質問に関連するいくつかの良い答えもあります 。Pythonの呼び出し元スレッドでスレッドの例外をキャッチする

于 2011-07-29T00:37:00.457 に答える
2

Python2.3を使用してスタック

Python2.3は今では10年前のものです。なぜまだ使っているのですか?

おそらくスレッディングモジュールを使用する

とにかくスレッドを使用する必要があります。

あなたはおそらく問題について間違って考えているでしょう。おそらく、いくつかのクラスを作成して、問題へのアプローチを再考する必要があります。

また、ウォッチドッグを作成している場合は、実行しているのと同じプロセスでウォッチドッグを作成することはおそらくあまり意味がありません。time.sleep()は、通常のPythonExceptionがとにかくキャンセルしないシステムコールです。

于 2011-07-28T23:53:53.833 に答える
1

Python 2.3の使用に固執していることは知っていますが、Python 2.4に(非常に)控えめな進歩しかできない場合は、Yaroslav Bulatovの回答から質問にコピーした、このより簡単なアプローチを利用できます(推奨読書)タイムアウト付きの外部コマンドの実行について:Python、Popen、select-プロセスの終了またはタイムアウトの待機

from threading import Timer
from subprocess import Popen, PIPE

def kill_proc():
    proc.kill()

proc = Popen("count_to_10.exe", shell=True)
t = Timer(60, kill_proc)
t.start()
proc.wait()

これは、以前の回答で述べたように、親プロセスが子プロセスをタイムアウトする例です。

于 2011-08-09T23:14:04.337 に答える