IT

완료하는 데 시간이 너무 오래 걸리는 경우 타임 아웃 기능

lottoking 2020. 6. 25. 07:45
반응형

완료하는 데 시간이 너무 오래 걸리는 경우 타임 아웃 기능 [중복]


이 질문에는 이미 답변이 있습니다.

방문하고 스크린 샷을 찍고 싶은 URL이 포함 된 텍스트 파일을 반복하는 쉘 스크립트가 있습니다.

이 모든 것이 간단하고 간단합니다. 이 스크립트는 실행될 때 목록에있는 각 사이트의 스크린 샷을 생성하는 클래스를 초기화합니다. 일부 사이트는로드하는 데 시간이 오래 걸리고 일부는 전혀로드되지 않을 수 있습니다. 그래서 screengrabber 함수를 타임 아웃 스크립트로 감싸서 False10 초 이내에 완료되지 않으면 함수가 반환되도록하고 싶습니다 .

가능한 가장 간단한 솔루션에 만족하고 있습니다. 실제로 함수 내부에서 어떤 일이 발생하더라도 10 초 후에 False를 반환하는 비동기 타이머를 설정합니까?


작동 시간 초과 프로세스는 신호 설명서에 설명되어 있습니다.

기본 아이디어는 신호 처리기를 사용하여 일정 시간 간격 동안 알람을 설정하고 타이머가 만료되면 예외를 발생시키는 것입니다.

이것은 UNIX에서만 작동합니다.

다음은 데코레이터를 생성하는 구현입니다 (다음 코드를로 저장 timeout.py).

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.alarm(seconds)
            try:
                result = func(*args, **kwargs)
            finally:
                signal.alarm(0)
            return result

        return wraps(func)(wrapper)

    return decorator

@timeout장기 실행 함수에 적용 할 수 있는 데코레이터를 만듭니다 .

따라서 응용 프로그램 코드에서 데코레이터를 다음과 같이 사용할 수 있습니다.

from timeout import timeout

# Timeout a long running function with the default expiry of 10 seconds.
@timeout
def long_running_function1():
    ...

# Timeout after 5 seconds
@timeout(5)
def long_running_function2():
    ...

# Timeout after 30 seconds, with the error "Connection timed out"
@timeout(30, os.strerror(errno.ETIMEDOUT))
def long_running_function3():
    ...

나는 with진술을 사용하여 David의 대답을 다시 썼다 .

with timeout(seconds=3):
    time.sleep(4)

TimeoutError가 발생합니다.

이 코드는 여전히 signalUNIX를 사용 하고 있습니다.

import signal

class timeout:
    def __init__(self, seconds=1, error_message='Timeout'):
        self.seconds = seconds
        self.error_message = error_message
    def handle_timeout(self, signum, frame):
        raise TimeoutError(self.error_message)
    def __enter__(self):
        signal.signal(signal.SIGALRM, self.handle_timeout)
        signal.alarm(self.seconds)
    def __exit__(self, type, value, traceback):
        signal.alarm(0)

참고URL : https://stackoverflow.com/questions/2281850/timeout-function-if-it-takes-too-long-to-finish

반응형