Python装饰器限制函数运行时间超时则退出执行


Posted in Python onApril 09, 2019

实际项目中会涉及到需要对有些函数的响应时间做一些限制,如果超时就退出函数的执行,停止等待。

可以利用python中的装饰器实现对函数执行时间的控制。

python装饰器简单来说可以在不改变某个函数内部实现和原来调用方式的前提下对该函数增加一些附件的功能,提供了对该函数功能的扩展。

方法一. 使用 signal

# coding=utf-8
import signal
import time
def set_timeout(num, callback):
  def wrap(func):
    def handle(signum, frame): # 收到信号 SIGALRM 后的回调函数,第一个参数是信号的数字,第二个参数是the interrupted stack frame.
      raise RuntimeError
    def to_do(*args, **kwargs):
      try:
        signal.signal(signal.SIGALRM, handle) # 设置信号和回调函数
        signal.alarm(num) # 设置 num 秒的闹钟
        print('start alarm signal.')
        r = func(*args, **kwargs)
        print('close alarm signal.')
        signal.alarm(0) # 关闭闹钟
        return r
      except RuntimeError as e:
        callback()
    return to_do
  return wrap
def after_timeout(): # 超时后的处理函数
  print("Time out!")
@set_timeout(2, after_timeout) # 限时 2 秒超时
def connect(): # 要执行的函数
  time.sleep(3) # 函数执行时间,写大于2的值,可测试超时
  print('Finished without timeout.')
if __name__ == '__main__':
  connect()

方法一中使用的signal有所限制,需要在linux系统上,并且需要在主线程中使用。方法二使用线程计时,不受此限制。

方法二. 使用Thread

# -*- coding: utf-8 -*-
from threading import Thread
import time
class TimeoutException(Exception):
  pass
ThreadStop = Thread._Thread__stop
def timelimited(timeout):
  def decorator(function):
    def decorator2(*args,**kwargs):
      class TimeLimited(Thread):
        def __init__(self,_error= None,):
          Thread.__init__(self)
          self._error = _error
        def run(self):
          try:
            self.result = function(*args,**kwargs)
          except Exception,e:
            self._error = str(e)
        def _stop(self):
          if self.isAlive():
            ThreadStop(self)
      t = TimeLimited()
      t.start()
      t.join(timeout)
      if isinstance(t._error,TimeoutException):
        t._stop()
        raise TimeoutException('timeout for %s' % (repr(function)))
      if t.isAlive():
        t._stop()
        raise TimeoutException('timeout for %s' % (repr(function)))
      if t._error is None:
        return t.result
    return decorator2
  return decorator
@timelimited(2) # 设置运行超时时间2S
def fn_1(secs):
  time.sleep(secs)
  return 'Finished without timeout'
def do_something_after_timeout():
  print('Time out!')
if __name__ == "__main__":
  try:
    print(fn_1(3)) # 设置函数执行3S
  except TimeoutException as e:
    print(str(e))
    do_something_after_timeout()

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。如果你想了解更多相关内容请查看下面相关链接

Python 相关文章推荐
python发布模块的步骤分享
Feb 21 Python
Python自动化测试ConfigParser模块读写配置文件
Aug 15 Python
Python标准库sched模块使用指南
Jul 06 Python
Python实现按照指定要求逆序输出一个数字的方法
Apr 19 Python
详解Django+uwsgi+Nginx上线最佳实战
Mar 14 Python
Python变量访问权限控制详解
Jun 29 Python
Python列表与元组的异同详解
Jul 02 Python
基于python3抓取pinpoint应用信息入库
Jan 08 Python
python内打印变量之%和f的实例
Feb 19 Python
Python requests上传文件实现步骤
Sep 15 Python
Python新建项目自动添加介绍和utf-8编码的方法
Dec 26 Python
python语言中pandas字符串分割str.split()函数
Aug 05 Python
详解Python 解压缩文件
Apr 09 #Python
Python使用pandas和xlsxwriter读写xlsx文件的方法示例
Apr 09 #Python
Python中使用logging和traceback模块记录日志和跟踪异常
Apr 09 #Python
由Python编写的MySQL管理工具代码实例
Apr 09 #Python
python实现爬山算法的思路详解
Apr 09 #Python
Python使用Pickle模块进行数据保存和读取的讲解
Apr 09 #Python
Python爬取数据保存为Json格式的代码示例
Apr 09 #Python
You might like
php单件模式结合命令链模式使用说明
2008/09/07 PHP
PHP之APC缓存详细介绍 apc模块安装
2014/01/13 PHP
ThinkPHP分页实例
2014/10/15 PHP
php中请求url的五种方法总结
2017/07/13 PHP
PHP基于redis计数器类定义与用法示例
2018/02/08 PHP
Prototype源码浅析 Enumerable部分之each方法
2012/01/16 Javascript
基于Jquery实现键盘按键监听
2014/05/11 Javascript
Javascript中3种实现继承的方法和代码实例
2014/08/12 Javascript
jQuery提示效果代码分享
2014/11/20 Javascript
AngularJS 单元测试(一)详解
2016/09/21 Javascript
微信小程序实现登录页云层漂浮的动画效果
2017/05/05 Javascript
jQuery+SpringMVC中的复选框选择与传值实例
2018/01/08 jQuery
使用vux实现上拉刷新功能遇到的坑
2018/02/08 Javascript
vue中实现先请求数据再渲染dom分享
2018/03/17 Javascript
Vue实现自定义下拉菜单功能
2018/07/16 Javascript
详解如何模拟实现node中的Events模块(通俗易懂版)
2019/04/15 Javascript
微信小程序自定义可滑动顶部TabBar选项卡实现页面切换功能示例
2019/05/14 Javascript
如何让微信小程序页面之间的通信不再变困难
2019/06/03 Javascript
JS代码检查工具ESLint介绍与使用方法
2020/02/04 Javascript
[02:36]DOTA2亚洲邀请赛小组赛精彩集锦:奇迹哥卡尔秀翻全场
2017/03/28 DOTA
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
python使用标准库根据进程名如何获取进程的pid详解
2017/10/31 Python
wxPython实现窗口用图片做背景
2018/04/25 Python
Sanic框架应用部署方法详解
2018/07/18 Python
Django中数据库的数据关系:一对一,一对多,多对多
2018/10/21 Python
Python高级特性与几种函数的讲解
2019/03/08 Python
Python数据可视化:箱线图多种库画法
2019/11/06 Python
Python实现加密接口测试方法步骤详解
2020/06/05 Python
Python如何使用vars返回对象的属性列表
2020/10/17 Python
澳大利亚在线批发商:Simply Wholesale
2021/02/24 全球购物
办公室文员工作自我评价
2013/12/01 职场文书
宾馆总经理岗位职责
2014/02/14 职场文书
应届生求职自荐信范文
2014/04/07 职场文书
先进党支部事迹材料
2014/12/24 职场文书
2016年暑期教师培训心得体会
2016/01/09 职场文书
2016大学生暑期社会实践心得体会
2016/01/14 职场文书