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 MD5文件生成码
Jan 12 Python
python实现问号表达式(?)的方法
Nov 27 Python
python连接mysql数据库示例(做增删改操作)
Dec 31 Python
利用Anaconda简单安装scrapy框架的方法
Jun 13 Python
python3解析库BeautifulSoup4的安装配置与基本用法
Jun 26 Python
实例讲解python中的序列化知识点
Oct 08 Python
python实现归并排序算法
Nov 22 Python
Python构建图像分类识别器的方法
Jan 12 Python
python 消费 kafka 数据教程
Dec 21 Python
PyQt5+Pycharm安装和配置图文教程详解
Mar 24 Python
PIP和conda 更换国内安装源的方法步骤
Sep 21 Python
Matplotlib可视化之添加让统计图变得简单易懂的注释
Jun 11 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性能的原理介绍
2012/09/05 PHP
如何实现浏览器上的右键菜单
2006/07/10 Javascript
javascript 写类方式之三
2009/07/05 Javascript
ExtJS自定义主题(theme)样式详解
2013/11/18 Javascript
javascript利用apply和arguments复用方法
2013/11/25 Javascript
js实现按Ctrl+Enter发送效果
2014/09/18 Javascript
自定义jQuery插件方式实现强制对象重绘的方法
2015/03/23 Javascript
js中unicode转码方法详解
2015/10/09 Javascript
在Vue项目中使用d3.js的实例代码
2018/05/01 Javascript
基于Vue的延迟加载插件vue-view-lazy
2018/05/21 Javascript
解决vue同一slot在组件中渲染多次的问题
2018/09/06 Javascript
给localStorage设置一个过期时间的方法分享
2018/11/06 Javascript
python使用smtplib模块通过gmail实现邮件发送的方法
2015/05/08 Python
Python socket编程实例详解
2015/05/27 Python
python自动裁剪图像代码分享
2017/11/25 Python
Python实现对文件进行单词划分并去重排序操作示例
2018/07/10 Python
Sanic框架路由用法实例分析
2018/07/16 Python
使用Python获取网段IP个数以及地址清单的方法
2018/11/01 Python
基于Python获取城市近7天天气预报
2019/11/26 Python
在Pytorch中计算卷积方法的区别详解(conv2d的区别)
2020/01/03 Python
浅谈keras的深度模型训练过程及结果记录方式
2020/01/24 Python
解决TensorFlow训练内存不断增长,进程被杀死问题
2020/02/05 Python
python GUI库图形界面开发之PyQt5布局控件QGridLayout详细使用方法与实例
2020/03/06 Python
python中的yield from语法快速学习
2020/11/06 Python
详解HTML5中ol标签的用法
2015/09/08 HTML / CSS
美国祛痘、抗衰老药妆品牌:Murad
2016/08/27 全球购物
英国轻奢珠宝品牌:Astley Clarke
2016/12/18 全球购物
加拿大折扣、优惠券和交易网站:WagJag
2018/02/07 全球购物
Oasis服装官网:时尚女装在线
2020/07/09 全球购物
历史专业毕业生的自我鉴定
2013/11/15 职场文书
网页美工求职信
2014/02/15 职场文书
爱岗敬业事迹材料
2014/12/24 职场文书
运动会加油稿
2015/07/22 职场文书
Pandas数据结构之Series的使用
2022/03/31 Python
使用Ajax实现进度条的绘制
2022/04/07 Javascript
服务器nginx权限被拒绝解决案例
2022/09/23 Servers