본문 바로가기
파이썬

파이썬 완료하는 데 너무 오래 걸리는 경우 시간 초과 기능

by º기록 2020. 12. 17.
반응형

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

이 모든 것이 완료되고 간단합니다. 스크립트는 실행시 목록에있는 각 사이트의 스크린 샷을 만드는 클래스를 초기화합니다. 일부 사이트는로드하는 데 매우 오랜 시간이 걸리며 일부 사이트는 전혀로드되지 않을 수 있습니다. 그래서 저는 screengrabber-function을 타임 아웃 스크립트로 감싸고 싶습니다. 10 초 안에 끝낼 수 없다면 함수가 False 를 반환하도록 만들고 싶습니다.

가능한 가장 간단한 솔루션에 만족합니다. 함수 내부에서 실제로 어떤 일이 발생하더라도 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():
    ...

 

참조 페이지 https://stackoverflow.com/questions/2281850

 

 

반응형

댓글