Python执行超时处理

        在执行python过程中,可能出现某个函数卡死的情况,通常的处理方法是手工终止程序运行。那如何能让脚本自动处理呢?网上有很多用signal库处理的例子,但signal只能在linux下使用,在windows下无法使用。在windows下可以使用另外一个方法KThread,Kthread继承了threading.Thread类并实现了kill方法。下面是整理的处理方法和调用方法。

一、方法

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"""

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

if alive:

# raise Timeout(u'function run too long, timeout %d seconds.' % seconds)

try:

raise Timeout('function run too long, timeout {0} seconds.'.format(seconds))

finally:

module_logger.warning('function run too long, timeout {0} seconds.'.format(seconds))

return 'Error', 'function run too long, timeout {0} seconds.'.format(seconds)

else:

return result[0]

_.__name__ = func.__name__

_.__doc__ = func.__doc__

return _

return timeout_decorator

二、使用装饰器调用实例

@testenv.timeout(60)

defmove_to_element_by_actionchains(se_driver,el,obj_attr,style):

你可能感兴趣的:(Python执行超时处理)