関数呼び出しのタイムアウト 質問する

関数呼び出しのタイムアウト 質問する

Python で関数を呼び出していますが、関数が停止してスクリプトを強制的に再起動しなければならない可能性があります。

5 秒以上かかる場合にスクリプトがそれをキャンセルして別の処理を実行するようにするには、関数をどのように呼び出すか、または何で関数をラップすればよいでしょうか?

ベストアンサー1

あなたは信号UNIX 上で実行している場合はパッケージ:

In [1]: import signal

# Register an handler for the timeout
In [2]: def handler(signum, frame):
   ...:     print("Forever is over!")
   ...:     raise Exception("end of time")
   ...: 

# This function *may* run for an indetermined time...
In [3]: def loop_forever():
   ...:     import time
   ...:     while 1:
   ...:         print("sec")
   ...:         time.sleep(1)
   ...:         
   ...:         

# Register the signal function handler
In [4]: signal.signal(signal.SIGALRM, handler)
Out[4]: 0

# Define a timeout for your function
In [5]: signal.alarm(10)
Out[5]: 0

In [6]: try:
   ...:     loop_forever()
   ...: except Exception, exc: 
   ...:     print(exc)
   ....: 
sec
sec
sec
sec
sec
sec
sec
sec
Forever is over!
end of time

# Cancel the timer if the function returned before timeout
# (ok, mine won't but yours maybe will :)
In [7]: signal.alarm(0)
Out[7]: 0

呼び出しから 10 秒後にsignal.alarm(10)、ハンドラが呼び出されます。これにより、通常の Python コードからインターセプトできる例外が発生します。

このモジュールはスレッドではうまく動作しません (しかし、誰がそうするのでしょうか?)

タイムアウトが発生すると例外が発生するため、関数内で例外がキャッチされ無視される可能性があることに注意してください。たとえば、次のような関数があります。

def loop_forever():
    while 1:
        print('sec')
        try:
            time.sleep(10)
        except:
            continue

おすすめ記事