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中操作字符串之replace()方法的使用
May 19 Python
Python去除字符串两端空格的方法
May 21 Python
python matplotlib画图实例代码分享
Dec 27 Python
Python解析命令行读取参数--argparse模块使用方法
Jan 23 Python
python3之模块psutil系统性能信息使用
May 30 Python
Flask框架实现给视图函数增加装饰器操作示例
Jul 16 Python
浅谈Python脚本开头及导包注释自动添加方法
Oct 27 Python
django数据库自动重连的方法实例
Jul 21 Python
Python imread、newaxis用法详解
Nov 04 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
Jun 11 Python
python如何修改文件时间属性
Feb 05 Python
python 使用pandas读取csv文件的方法
Dec 24 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中使用glob函数实现一句话删除某个目录下的所有文件
2014/07/22 PHP
PHP整合七牛实现上传文件
2015/07/03 PHP
javascript模仿msgbox提示效果代码
2008/06/10 Javascript
javascript中的变量是传值还是传址的?
2010/04/19 Javascript
Jquery 类网页微信二维码图块滚动效果具体实现
2013/10/14 Javascript
浅析JavaScript中的类型和对象
2013/11/29 Javascript
JS实现倒计时和文字滚动的效果实例
2014/10/29 Javascript
javascript每日必学之基础入门
2016/02/16 Javascript
全面理解JavaScript中的继承(必看)
2016/06/16 Javascript
Js查找字符串中出现次数最多的字符及个数实例解析
2016/09/05 Javascript
javascript表单控件实例讲解
2016/09/13 Javascript
详解基于webpack2.x的vue2.x的多页面站点
2017/08/21 Javascript
npm 更改默认全局路径以及国内镜像的方法
2018/05/16 Javascript
vue.js将时间戳转化为日期格式的实现代码
2018/06/05 Javascript
Vuex的基本概念、项目搭建以及入坑点
2018/11/04 Javascript
从零开始实现Vue简单的Toast插件
2018/12/03 Javascript
微信小程序结合mock.js实现后台模拟及调试
2019/03/28 Javascript
Vue编程式跳转的实例代码详解
2019/07/10 Javascript
javaScript中indexOf用法技巧
2019/11/26 Javascript
JS实现烟花爆炸效果
2020/03/10 Javascript
[02:02]特效爆炸!DOTA2珍宝之瓶待你开启
2018/08/21 DOTA
pygame学习笔记(2):画点的三种方法和动画实例
2015/04/15 Python
python pyheatmap包绘制热力图
2018/11/09 Python
Python中面向对象你应该知道的一下知识
2019/07/10 Python
django Admin文档生成器使用详解
2019/07/22 Python
TensorFlow基于MNIST数据集实现车牌识别(初步演示版)
2019/08/05 Python
Python面向对象原理与基础语法详解
2020/01/02 Python
pytorch中的weight-initilzation用法
2020/06/24 Python
CSS3 text-shadow实现文字阴影效果
2016/02/24 HTML / CSS
Under Armour美国官网:美国知名高端功能性运动品牌
2016/09/05 全球购物
Kate Spade澳大利亚官方网站:美国设计师手袋品牌
2019/09/10 全球购物
电脑教师的教学自我评价
2013/11/26 职场文书
承认错误的检讨书
2014/01/30 职场文书
班主任高考寄语
2015/02/26 职场文书
教师个人教学反思
2016/02/23 职场文书
如何用python插入独创性声明
2021/03/31 Python