22

問題の仕様:

ログファイルの非常に多くの行を検索しており、関数を使用して保存した正規表現 (RegExses) のために、これらの行をグループに配布していre.match()ます。残念ながら、私の正規表現のいくつかは複雑すぎて、Python が後戻り地獄に陥ることがあります。このため、何らかのタイムアウトで保護する必要があります。

問題:

  • re.match、私が使用しているのはPythonの関数であり、StackOverflowのどこかで見つけたように(本当に申し訳ありませんが、現在リンクが見つかりません:-( )。実行中のPythonのライブラリでスレッドを中断することは非常に困難です。このため、スレッドはゲームから外れています。
  • 関数の評価にre.matchは比較的短い時間がかかり、この関数を使用して大量の行を分析したいため、実行に時間がかかりすぎないタイムアウト関数が必要です(これにより、スレッドがさらに適切ではなくなり、初期化に非常に長い時間がかかります)新しいスレッド)であり、1 秒未満に設定できます
    これらの理由から、ここでの回答 -関数呼び出しのタイムアウト と ここ -デコレーターで終了するのに時間がかかりすぎる場合のタイムアウト機能(アラーム - 1秒以上) はテーブルから外れています。

今朝、この質問の解決策を探しましたが、満足のいく答えが見つかりませんでした。

4

1 に答える 1

41

解決:

ここに投稿されたスクリプトを変更しました: Timeout function if it takes too long to finish .

コードは次のとおりです。

from functools import wraps
import errno
import os
import signal

class TimeoutError(Exception):
    pass

def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
    def decorator(func):
        def _handle_timeout(signum, frame):
            raise TimeoutError(error_message)

        def wrapper(*args, **kwargs):
            signal.signal(signal.SIGALRM, _handle_timeout)
            signal.setitimer(signal.ITIMER_REAL,seconds) #used timer instead of alarm
            try:
                result = func(*args, **kwargs)
            finally:
                signal.alarm(0)
            return result
        return wraps(func)(wrapper)
    return decorator

そして、次のように使用できます。

from timeout import timeout 
from time import time

@timeout(0.01)
def loop():
    while True:
       pass
try:
    begin = time.time()
    loop()
except TimeoutError, e:
    print "Time elapsed: {:.3f}s".format(time.time() - begin)

どのプリント

Time elapsed: 0.010s
于 2012-08-10T12:18:10.613 に答える