Python装饰器限制函数运行时间超时则退出执行

作者:-牧野- 时间:2022-09-07 18:12:54 

实际项目中会涉及到需要对有些函数的响应时间做一些限制,如果超时就退出函数的执行,停止等待。

可以利用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()

来源:https://blog.csdn.net/dcrmg/article/details/82850457

标签:python,装饰器,限制函数运行时间
0
投稿

猜你喜欢

  • mysql与sqlserver的所有区别

    2009-02-27 16:18:00
  • Pycharm设置去除显示的波浪线方法

    2022-06-29 16:04:59
  • python制作的天气预报小工具(gui界面)

    2022-04-03 17:20:42
  • 一文详述 Python 中的 property 语法

    2023-04-03 03:38:01
  • YOLOv5车牌识别实战教程(六)性能优化与部署

    2022-04-26 12:40:54
  • 超详细注释之OpenCV更改像素与修改图像通道

    2021-07-01 17:42:45
  • oracle下实现恢复一个丢失的数据文件的代码

    2009-03-02 11:02:00
  • 如何使用Oracle PL/SQL 实现发送电子邮件功能(UTL_MAIL)

    2024-01-17 19:32:18
  • Window.Open详解

    2008-06-08 13:43:00
  • YUI学习笔记(4)

    2009-03-10 18:25:00
  • ubuntu系统下切换python版本的方法

    2021-07-05 18:12:50
  • javascript自定义函数参数传递为字符串格式

    2024-04-22 13:08:18
  • php5.3 不支持 session_register() 此函数已启用的解决方法

    2023-11-16 01:59:39
  • Mysql中实现提取字符串中的数字的自定义函数分享

    2024-01-25 10:56:20
  • 解决MySQL数据库链接超时报1129错误问题

    2024-01-17 12:15:04
  • 基于scrapy实现的简单蜘蛛采集程序

    2023-09-22 03:58:02
  • python break和continue用法对比

    2021-11-03 14:36:20
  • “尊重”设计师?

    2009-03-23 18:14:00
  • Asp生成RSS的类_给网站加上RSS

    2011-04-19 11:06:00
  • CentOS 7安装MySQL的详细步骤

    2024-01-25 19:59:17
  • asp之家 网络编程 m.aspxhome.com