2014-02-17 2 views
8

특정 기능에 대한 시간 제한을 구현하려고합니다. 내가 Windows에서 파이썬을 실행하고윈도우에서 파이썬 기능을 시간 초과합니다.

  1. 때문에
  2. 제한 시간은 내가이없는 파이썬 기능을 적용, SE에서 많은 질문 확인하고 내 문제에 맞는 모든 솔루션을 찾을 수 없습니다 컨트롤은 이미 정의 된 모듈에서 정의됩니다.
  3. 파이썬 함수는 하위 프로세스

나는 이미 설계된 사용자 정의 모듈을 데없는 특정 작업을 위해 개발 (인 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을 기반으로 작성되었습니다.

답변

13

나는 이것을 접근하는 좋은 방법은 데코레이터를 만들고 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(): 
    ... 
+1

답변 해 주셔서 감사합니다. 위의 데코레이터 기능을 시도하고 예상대로 작동합니다. 내가해야하는 유일한 변화는 'func'에 넣는 대신 "MyResult = timeout (timeout = 16) (MyModule.MyFunc) (MyArgs)"입니다. – punarvak

+0

문제가 없습니다. 두 가지 방법으로 작동해야하지만 timeout (timeout = 16) (MyModule.MyFunc)은 args를 호출 할 수있는 함수를 반환합니다. – acushner

+4

예! 마침내 신호에 포함되지 않은 좋은 대답을 발견했습니다 (알람 기능은 Windows에서 작동하지 않습니다). @ 감사합니다. – propjk007

0

@ 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 
관련 문제