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连接MySQL、MongoDB、Redis、memcache等数据库的方法
Nov 15 Python
django模型中的字段和model名显示为中文小技巧分享
Nov 18 Python
python制作填词游戏步骤详解
May 05 Python
Python基于read(size)方法读取超大文件
Mar 12 Python
利用 PyCharm 实现本地代码和远端的实时同步功能
Mar 23 Python
Python3 selenium 实现QQ群接龙自动化功能
Apr 17 Python
解决python cv2.imread 读取中文路径的图片返回为None的问题
Jun 02 Python
DRF框架API版本管理实现方法解析
Aug 21 Python
详解python polyscope库的安装和例程
Nov 13 Python
python爬虫搭配起Bilibili唧唧的流程分析
Dec 01 Python
pycharm 2020.2.4 pip install Flask 报错 Error:Non-zero exit code的问题
Dec 04 Python
python爬虫beautifulsoup库使用操作教程全解(python爬虫基础入门)
Feb 19 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
自己动手,丰衣足食 - 短波框形天线制作
2021/03/01 无线电
Symfony2实现在controller中获取url的方法
2016/03/18 PHP
php操纵mysqli数据库的实现方法
2016/09/18 PHP
非常有用的40款jQuery 插件推荐(系列二)
2011/12/25 Javascript
JS中showModalDialog 的使用解析
2013/04/17 Javascript
Jquery遍历节点的方法小集
2014/01/22 Javascript
jquery自定义滚动条插件示例分享
2014/02/21 Javascript
用Move.js配合创建CSS3动画的入门指引
2015/07/22 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
详解javascript遍历方式
2015/11/11 Javascript
AngularJs中 ng-repeat指令中实现含有自定义指令的动态html的方法
2017/01/19 Javascript
jQuery 实时保存页面动态添加的数据的示例
2017/08/14 jQuery
浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
2018/12/20 Javascript
详释JavaScript执行环境与执行栈
2019/04/02 Javascript
vue3.0 搭建项目总结(详细步骤)
2019/05/20 Javascript
jquery轻量级数字动画插件countUp.js使用详解
2019/10/17 jQuery
Vue实现仿iPhone悬浮球的示例代码
2020/03/13 Javascript
微信小程序实现可长按移动控件
2020/11/01 Javascript
Python中的模块和包概念介绍
2015/04/13 Python
python脚本设置系统时间的两种方法
2016/02/21 Python
Python构建网页爬虫原理分析
2017/12/19 Python
Python 判断奇数偶数的方法
2018/12/20 Python
Python实现的读取文件内容并写入其他文件操作示例
2019/04/09 Python
解决django后台管理界面添加中文内容乱码问题
2019/11/15 Python
TensorFlow tf.nn.conv2d_transpose是怎样实现反卷积的
2020/04/20 Python
利用Python实现斐波那契数列的方法实例
2020/07/26 Python
Python中正则表达式对单个字符,多个字符和匹配边界等使用
2021/01/27 Python
CSS3实现王者匹配时的粒子动画效果
2019/04/12 HTML / CSS
世界上最大的家庭自动化公司:Smarthome
2017/12/20 全球购物
King Apparel官网:英国街头服饰品牌
2019/09/05 全球购物
将"引用"作为函数返回值类型的格式、好处和需要遵守的规则
2016/02/09 面试题
先进工作者获奖感言
2014/02/08 职场文书
《庐山的云雾》教学反思
2014/04/22 职场文书
2015年元旦文艺晚会总结(学院)
2014/11/28 职场文书
导游词之沈阳清昭陵
2019/12/28 职场文书
基于Python实现流星雨效果的绘制
2022/03/18 Python