python 函數超時裝飾器

##### 不關乎主線程仍是子線程的超時裝飾器
#-*-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

相關文章
相關標籤/搜索