##### 不關乎主線程仍是子線程的超時裝飾器 #-*-coding:utf8-*- import os import threading import time import sys class KThread(threading.Thread): """A subclass of threading.Thread, with a kill() method. Come from: Kill a thread in Python: http://mail.python.org/pipermail/python-list/2004-May/260937.html """ def __init__(self, *args, **kwargs): threading.Thread.__init__(self, *args, **kwargs) self.killed = False def start(self): """Start the thread.""" self.__run_backup = self.run self.run = self.__run # Force the Thread to install our trace. threading.Thread.start(self) def __run(self): """Hacked run function, which installs the trace.""" sys.settrace(self.globaltrace) self.__run_backup() self.run = self.__run_backup def globaltrace(self, frame, why, arg): if why == 'call': return self.localtrace else: return None def localtrace(self, frame, why, arg): if self.killed: if why == 'line': raise SystemExit() return self.localtrace def kill(self): self.killed = True class Timeout(Exception): """function run timeout""" class Timeout(Exception): """function run timeout""" def timeout(seconds): """超時裝飾器,指定超時時間 若被裝飾的方法在指定的時間內未返回,則拋出Timeout異常""" def timeout_decorator(func): """真正的裝飾器""" def _new_func(oldfunc, result, oldfunc_args, oldfunc_kwargs): result.append(oldfunc(*oldfunc_args, **oldfunc_kwargs)) def _(*args, **kwargs): result = [] new_kwargs = { # create new args for _new_func, because we want to get the func return val to result list 'oldfunc': func, 'result': result, 'oldfunc_args': args, 'oldfunc_kwargs': kwargs } thd = KThread(target=_new_func, args=(), kwargs=new_kwargs) thd.start() thd.join(seconds) alive = thd.isAlive() thd.kill() # kill the child thread try: if alive: raise Timeout(u'function run too long, timeout %d seconds.' % seconds) else: return result[0] except: print '------%s-----\n'%new_kwargs _.__name__ = func.__name__ _.__doc__ = func.__doc__ return _ return timeout_decorator @timeout(8)
#簡單函數超時裝飾器,和簡單類方法超時裝飾器(限定liunx,主線程) import signal def handler(signum, frame): raise AssertionError def timeout(arg=10): def _deco(func): def __deco(self,*args,**kwargs): try: signal.signal(signal.SIGALRM, handler) signal.alarm(arg) ret=func(self,*args,**kwargs) signal.alarm(0) return ret except AssertionError: print("timeout,%s"%arg) return __deco return _deco
#-*-coding:utf8-*-html
import timepython
import signalapp
def handler(signum, frame):函數
raise AssertionError線程
def timeout(arg):code
def _deco(func):htm
def __deco(*args,**kwargs):ip
try:get
signal.signal(signal.SIGALRM, handler)it
signal.alarm(arg)
func(*args,**kwargs)
signal.alarm(0)
except AssertionError:
print "timeout,%s"%arg
return __deco
return _deco
@timeout(5)
def test(i=5):
time.sleep(i)
print "%d sleep time"%(i)
return i