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批量修改文件后缀示例代码分享
Dec 24 Python
分析用Python脚本关闭文件操作的机制
Jun 28 Python
Python网络编程中urllib2模块的用法总结
Jul 12 Python
Python的面向对象编程方式学习笔记
Jul 12 Python
Python制作词云的方法
Jan 03 Python
Python实现base64编码的图片保存到本地功能示例
Jun 22 Python
pyqt5 实现工具栏文字图片同时显示
Jun 13 Python
python写入文件自动换行问题的方法
Jul 05 Python
python爬虫 爬取超清壁纸代码实例
Aug 16 Python
python @classmethod 的使用场合详解
Aug 23 Python
Python如何将装饰器定义为类
Jul 30 Python
python 绘制场景热力图的示例
Sep 23 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 ? EasyUI DataGrid 资料存的方式介绍
2012/11/07 PHP
jquery 事件执行检测代码
2009/12/09 Javascript
jQuery 表格工具集
2010/04/25 Javascript
jquery DOM操作 基于命令改变页面
2010/05/06 Javascript
jQuery Tips 为AJAX回调函数传递额外参数的方法
2010/12/28 Javascript
jqgrid 简单学习笔记
2011/05/03 Javascript
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
jquery模拟SELECT下拉框取值效果
2013/10/23 Javascript
js Array操作的最简短最容易理解方法
2013/12/09 Javascript
JS和JQUERY获取页面大小,滚动条位置,元素位置(示例代码)
2013/12/14 Javascript
jQuery中live()方法用法实例
2015/01/19 Javascript
浅谈JavaScript 浏览器对象
2016/06/03 Javascript
angular分页指令操作
2017/01/09 Javascript
javascript 中null和undefined区分和比较
2017/04/19 Javascript
ES6新特性八:async函数用法实例详解
2017/04/21 Javascript
基于zTree树形菜单的使用实例
2017/12/25 Javascript
vue 本地环境跨域请求proxyTable的方法
2018/09/19 Javascript
vue项目使用axios发送请求让ajax请求头部携带cookie的方法
2018/09/26 Javascript
validform表单验证的实现方法
2019/03/08 Javascript
vue中@change兼容问题详解
2019/10/25 Javascript
浅谈TypeScript的类型保护机制
2020/02/23 Javascript
Python中文竖排显示的方法
2015/07/28 Python
python爬虫headers设置后无效的解决方法
2017/10/21 Python
对numpy中的where方法嵌套使用详解
2018/10/31 Python
使用python serial 获取所有的串口名称的实例
2019/07/02 Python
python对象转字典的两种实现方式示例
2019/11/07 Python
如何将anaconda安装配置的mmdetection环境离线拷贝到另一台电脑
2020/10/15 Python
使用python tkinter开发一个爬取B站直播弹幕工具的实现代码
2021/02/07 Python
CSS3 实现弹幕的示例代码
2017/08/07 HTML / CSS
法国时尚童装网站:Melijoe
2016/08/10 全球购物
质量承诺书怎么写
2014/05/24 职场文书
中药学专业求职信
2014/05/31 职场文书
小学学校评估方案
2014/06/08 职场文书
银行主办会计岗位职责
2014/08/13 职场文书
2015年国庆节活动总结
2015/03/23 职场文书
mysql 数据插入优化方法之concurrent_insert
2021/07/01 MySQL