[Python] 타임아웃 적용하기

개발을 하다보면 함수에 타임아웃을 적용해서 일정 시간이 지나면 함수를 종료시켜야 하는 경우가 있다. 가끔 있는 일이지만 막상 필요할 때 생각이 잘 안 나서 정리해두었다.

Context manager로 사용하는 방법

import signal
from contextlib import contextmanager


@contextmanager
def timeout(time):
    signal.signal(signal.SIGALRM, raise_timeout)
    signal.alarm(time)
    try:
        yield
    except TimeoutError:
        pass
    finally:
        signal.signal(signal.SIGALRM, signal.SIG_IGN)


def raise_timeout(signum, frame) -> None:
    raise TimeoutError()


with timeout(5):
    while True:
        # do something...

Decorator로 사용하는 방법

import signal


def timeout(time):
    def wrapper(func):
        def processor(*args, **kwargs):
            signal.signal(signal.SIGALRM, raise_timeout)
            signal.alarm(time)
            try:
                return func(*args, **kwargs)
            except TimeoutError:
                pass
            finally:
                signal.signal(signal.SIGALRM, signal.SIG_IGN)
        return processor
    return wrapper


def raise_timeout(signum, frame) -> None:
    raise TimeoutError()


@timeout(5)
def func():
    while True:
        # do something...

비슷한 방법으로 threading.Timer를 이용한 방법도 있는데 signal을 이용한 방법이 더 깔끔해 보인다.

참고


Written by@EHX
Software Developer, Back-End Engineer

GitHubFacebook