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中的MongoDB基本操作:连接、查询实例
Feb 13 Python
Python中使用PDB库调试程序
Apr 05 Python
python pycurl验证basic和digest认证的方法
May 02 Python
numpy 进行数组拼接,分别在行和列上合并的实例
May 08 Python
使用Python编写Prometheus监控的方法
Oct 15 Python
python将excel转换为csv的代码方法总结
Jul 03 Python
django 通过URL访问上传的文件方法
Jul 28 Python
python通过链接抓取网站详解
Nov 20 Python
Python调用钉钉自定义机器人的实现
Jan 03 Python
python与mysql数据库交互的实现
Jan 06 Python
Jupyter notebook运行Spark+Scala教程
Apr 10 Python
利用Python第三方库实现预测NBA比赛结果
Jun 21 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/06/07 PHP
linux下 C语言对 php 扩展
2008/12/14 PHP
php 获取select下拉列表框的值
2010/05/08 PHP
jQuery+PHP发布的内容进行无刷新分页(Fckeditor)
2015/10/22 PHP
php批量删除操作(数据访问)
2017/05/23 PHP
php微信公众号开发之答题连闯三关
2018/10/20 PHP
createElement与createDocumentFragment的点点区别小结
2011/12/19 Javascript
使用javascipt---实现二分查找法
2013/04/10 Javascript
js判断字符是否是汉字的两种方法小结
2014/01/03 Javascript
判断在css加载完毕后执行后续代码示例
2014/09/03 Javascript
JS实现选项卡实例详解
2015/11/17 Javascript
如何在Angular2中使用jQuery及其插件的方法
2017/02/09 Javascript
干货!教大家如何选择Vue和React
2017/03/13 Javascript
最通俗易懂的javascript变量提升详解
2017/08/05 Javascript
vue基本使用--refs获取组件或元素的实例
2019/11/07 Javascript
js实现的在本地预览图片功能示例
2019/11/09 Javascript
vue 递归组件的简单使用示例
2021/01/14 Vue.js
python装饰器使用方法实例
2013/11/21 Python
简单介绍Python的Tornado框架中的协程异步实现原理
2015/04/23 Python
python编程线性回归代码示例
2017/12/07 Python
python3.6数独问题的解决
2019/01/21 Python
Django数据库类库MySQLdb使用详解
2019/04/28 Python
安装好Pycharm后如何配置Python解释器简易教程
2019/06/28 Python
python tkinter之 复选、文本、下拉的实现
2020/03/04 Python
解决pycharm导入numpy包的和使用时报错:RuntimeError: The current Numpy installation (‘D:\\python3.6\\lib\\site-packa的问题
2020/12/08 Python
利用python+request通过接口实现人员通行记录上传功能
2021/01/13 Python
python 数据类型强制转换的总结
2021/01/25 Python
CSS中的字体大小设置属性总结
2016/05/24 HTML / CSS
求职自荐信范文格式
2013/11/29 职场文书
餐厅楼面主管岗位职责范本
2014/02/16 职场文书
服装设计师职业生涯规划范文
2014/02/28 职场文书
党员创先争优活动总结
2014/05/04 职场文书
平安建设工作方案
2014/06/02 职场文书
优秀团队申报材料
2014/12/26 职场文书
2016年公司新年寄语
2015/08/17 职场文书
Windows Server 修改远程桌面端口的实现
2022/06/25 Servers