복붙노트

[PYTHON] 창에서 파이썬 기능 제한 시간 초과

PYTHON

창에서 파이썬 기능 제한 시간 초과

특정 함수에 대한 시간 초과를 구현하려고합니다. 내가 SE에서 많은 질문을 확인하고 내 문제에 맞는 솔루션을 찾을 수 없습니다. 왜냐하면

나는 이미 설계된 커스텀 모듈 (MyModule)이 특정 태스크를 위해 개발되었고, 거기에 정의 된 함수들이있다. 함수 중 하나 (MyFunc)는 외부 요인으로 인해 영원히 돌아가는 경향이 있으며 파이썬 스크립트가 멈추길 원치 않습니다.

아래에 설명 된 것처럼 시간 초과 기능을 추가 할 계획입니다. 의사 코드

    import MyModule

    set_timeout(T)
    MyResult=MyModule.MyFunc()

    #Come to this part of script after execution of MyFunc() or after T seconds (the latter on priority)
    if Timeout occurred:
        print 'MyFunc did not execute completely'
    else:
        print 'MyFunc completed'

그러나 파이썬에서이를 달성하기 위해 어떤 모듈을 사용할 수 있는지 확실하지 않습니다. 필자는 초보자이며 필자가 작성한 모든 스크립트는 SE Answers 또는 Python Documentation을 기반으로 작성되었습니다.

해결법

  1. ==============================

    1.이 방법에 접근하는 좋은 방법은 데코레이터를 만들고 Thread.join (timeout) 메서드를 사용하는 것입니다. 스레드를 죽이는 좋은 방법이 없다는 것을 명심하십시오. 따라서 프로그램이 실행되는 한 백그라운드에서 계속 실행될 것입니다.

    이 방법에 접근하는 좋은 방법은 데코레이터를 만들고 Thread.join (timeout) 메서드를 사용하는 것입니다. 스레드를 죽이는 좋은 방법이 없다는 것을 명심하십시오. 따라서 프로그램이 실행되는 한 백그라운드에서 계속 실행될 것입니다.

    먼저 다음과 같은 데코레이터를 만듭니다.

    from threading import Thread
    import functools
    
    def timeout(timeout):
        def deco(func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                res = [Exception('function [%s] timeout [%s seconds] exceeded!' % (func.__name__, timeout))]
                def newFunc():
                    try:
                        res[0] = func(*args, **kwargs)
                    except Exception, e:
                        res[0] = e
                t = Thread(target=newFunc)
                t.daemon = True
                try:
                    t.start()
                    t.join(timeout)
                except Exception, je:
                    print 'error starting thread'
                    raise je
                ret = res[0]
                if isinstance(ret, BaseException):
                    raise ret
                return ret
            return wrapper
        return deco
    

    다음과 같이하십시오.

    func = timeout(timeout=16)(MyModule.MyFunc)
    try:
        func()
    except:
        pass #handle errors here
    

    당신은 어디서나이 데코레이터를 사용할 수 있습니다 :

    @timeout(60)
    def f():
        ...
    
  2. ==============================

    2.@ acushner의 대답은 Python 3.5에 적합합니다.

    @ acushner의 대답은 Python 3.5에 적합합니다.

    from threading import Thread
    import functools
    
    def timeout(seconds_before_timeout):
        def deco(func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                res = [Exception('function [%s] timeout [%s seconds] exceeded!' % (func.__name__, seconds_before_timeout))]
                def newFunc():
                    try:
                        res[0] = func(*args, **kwargs)
                    except Exception as e:
                        res[0] = e
                t = Thread(target=newFunc)
                t.daemon = True
                try:
                    t.start()
                    t.join(seconds_before_timeout)
                except Exception as e:
                    print('error starting thread')
                    raise e
                ret = res[0]
                if isinstance(ret, BaseException):
                    raise ret
                return ret
            return wrapper
        return deco
    
  3. from https://stackoverflow.com/questions/21827874/timeout-a-python-function-in-windows by cc-by-sa and MIT license