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使用urllib模块开发的多线程豆瓣小站mp3下载器
Jan 16 Python
python在控制台输出进度条的方法
Jun 20 Python
Google开源的Python格式化工具YAPF的安装和使用教程
May 31 Python
浅谈python爬虫使用Selenium模拟浏览器行为
Feb 23 Python
利用Python批量提取Win10锁屏壁纸实战教程
Mar 27 Python
Pandas DataFrame 取一行数据会得到Series的方法
Nov 10 Python
python的schedule定时任务模块二次封装方法
Feb 19 Python
Python实现根据日期获取当天凌晨时间戳的方法示例
Apr 09 Python
Python求平面内点到直线距离的实现
Jan 19 Python
Python reduce函数作用及实例解析
May 08 Python
Python并发请求下限制QPS(每秒查询率)的实现代码
Jun 05 Python
Django给表单添加honeypot验证增加安全性
May 06 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
Zend Framework实现多文件上传功能实例
2016/03/21 PHP
总结PHP中初始化空数组的最佳方法
2019/02/13 PHP
JavaScript多线程的实现方法
2007/05/08 Javascript
基于Jquery的$.cookie()实现跨越页面tabs导航实现代码
2011/03/03 Javascript
js Select下拉列表框进行多选、移除、交换内容的具体实现方法
2013/08/13 Javascript
js同比例缩放图片的小例子
2013/10/30 Javascript
自己实现ajax封装示例分享
2014/04/01 Javascript
点击表单提交时出现jQuery没有权限的解决方法
2014/07/23 Javascript
js Calender控件使用详解
2015/01/05 Javascript
js实现checkbox全选、不选与反选的方法
2015/02/09 Javascript
浅析JavaScript中的事件机制
2015/06/04 Javascript
clipboard.js无需Flash无需依赖任何JS库实现文本复制与剪切
2015/10/10 Javascript
详解Matlab中 sort 函数用法
2016/03/20 Javascript
jQuery解决浏览器兼容性问题案例分析
2016/04/15 Javascript
使用Angular缓存父页面数据的方法
2017/01/03 Javascript
AngularJS service之select下拉菜单效果
2017/07/28 Javascript
Vue0.1的过滤代码如何添加到Vue2.0直接使用
2017/08/23 Javascript
element ui 表格动态列显示空白bug 修复方法
2018/09/04 Javascript
nodejs中方法和模块用法示例
2018/12/24 NodeJs
聊聊Vue 中 title 的动态修改问题
2019/06/11 Javascript
Javascript如何递归遍历本地文件夹
2020/08/06 Javascript
[44:04]OG vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
全面解析Python的While循环语句的使用方法
2015/10/13 Python
举例讲解Python的lambda语句声明匿名函数的用法
2016/07/01 Python
Python实现的人工神经网络算法示例【基于反向传播算法】
2017/11/11 Python
Python爬虫设置代理IP的方法(爬虫技巧)
2018/03/04 Python
HTML5表单验证特性(知识点小结)
2020/03/10 HTML / CSS
Lacoste美国官网:经典POLO衫品牌
2016/10/12 全球购物
银行门卫岗位职责
2013/12/29 职场文书
满月酒主持词
2014/03/27 职场文书
创建绿色社区汇报材料
2014/08/22 职场文书
计划生育证明书写要求
2014/09/17 职场文书
党员干部作风建设思想汇报范文
2014/10/25 职场文书
《围炉夜话》110句人生箴言,精辟有内涵,引人深思
2019/10/23 职场文书
漫画《催眠麦克风-Dawn Of Divisions》第二卷PV公开
2022/04/05 日漫
GO中sync包自由控制并发示例详解
2022/08/05 Golang