[Python] 使用 signal 和 decorator 讓函式執行超過時限時中斷

import signal

# seconds: 執行時限的最大秒數
# call_if_time_out: 超過執行時限後呼叫的函數
def time_limit(seconds, call_if_time_out=None):
  def wrapper(func):
    
    def handler(signum, frame):
      raise TimeoutError()
    
    def decorator(*args, **kwargs):
      signal.signal(signal.SIGALRM, handler) # SIGALRM: 定時器終止時傳送給行程的訊號
      signal.alarm(seconds) # 設置alarm
      try:
        res = func(*args, **kwargs)
      except TimeoutError as e: # 如果func裡有其他try expression可能導致無法擷取到上面raise的TimeoutError
        res = call_if_time_out() if call_if_time_out else e
      finally:
        signal.alarm(0) # 取消之前設置的alarm並回傳剩餘秒數
        return res
    
    return decorator
  return wrapper

@time_limit(...)
def ...(...):
  ...

 

Last Updated on 2023/08/16 by A1go

Bitnami