Pythonデコレータ タイムアウト
By hientd, at: 2022年11月11日15:28
Estimated Reading Time: __READING_TIME__ minutes
![[Python Decorators] Timeout](/media/filer_public_thumbnails/filer_public/5a/7b/5a7b20f3-880f-4589-bfc8-2d9010a5540a/python_decorator_-_timeout.png__1500x900_crop_subsampling-2_upscale.png)
![[Python Decorators] Timeout](/media/filer_public_thumbnails/filer_public/5a/7b/5a7b20f3-880f-4589-bfc8-2d9010a5540a/python_decorator_-_timeout.png__400x240_crop_subsampling-2_upscale.png)
timeout
デコレータはPythonにおいて、関数の実行時間を制限するために使用されます。関数が指定された時間よりも長く実行された場合、TimeoutException
を発生させます。これは、関数が無限にハングしないように保証したい場合に特に便利です。
ソースコード
import signal
class TimeoutException(Exception):
pass
def timeout(seconds):
def decorator(func):
def handler(signum, frame):
raise TimeoutException(f"Function {func.__name__} timed out after {seconds} seconds")
def wrapper(*args, **kwargs):
signal.signal(signal.SIGALRM, handler)
signal.alarm(seconds)
try:
result = func(*args, **kwargs)
finally:
signal.alarm(0)
return result
return wrapper
return decorator
@timeout(5)
def long_running_function():
import time
time.sleep(10)
try:
long_running_function()
except TimeoutException as e:
print(e) # Output: Function long_running_function timed out after 5 seconds
解説
- シグナル処理:
signal
モジュールを使用して、指定された時間後にトリガーされるアラームシグナルを設定します。
- TimeoutException: 関数が割り当てられた時間を超過すると、カスタム例外が発生します。
- デコレータ構造:
timeout
デコレータは対象関数をラップし、signal
を使用してタイミングロジックを管理します。
ユースケース
- ネットワークリクエスト: ネットワーク応答を待つ時間に制限を設定します。
- 長時間計算: 計算コストの高い関数が無限に実行されるのを防ぎます。
- リソース管理: 制限されたリソースにアクセスする関数がそれらを独占的に使用しないようにします。
制限事項
- プラットフォーム依存性:
signal
モジュールはUnixベースのシステムでのみ動作します。=>それを回避するには、Sentryなど、エラーを通知するいくつかの公開サービスを使用できます。
- スレッド安全性: シグナルはプロセス全体であるため、マルチスレッドアプリケーションには適していません。
timeout
デコレータを組み込むことで、プログラムをより堅牢にし、長時間実行される関数による潜在的なハングアップを防ぐことができます。