在 Linux/Mac 下为Python函数添加超时时间的方法


Posted in Python onFebruary 20, 2020

我们在使用 requests 这类网络请求第三方库时,可以看到它有一个参数叫做 timeout ,就是指在网络请求发出开始计算,如果超过 timeout 还没有收到返回,就抛出超时异常。(当然存在特殊情况timeout 会失效,请看Timeouts and cancellation for humans* 这篇文章中作者的举例,我们不考虑这种特殊情况)。

但大家有没有考虑过,如何为普通的函数设置超时时间?特别是在运行一些数据处理、AI 相关的代码时,某个函数可能会运行很长时间,我们想实现,在函数运行超过特定的时间时,自动报错。

例如有这样一个场景,我写了一个函数 calc_statistic(datas) ,根据用户传入的数据计算某个值。但如果用户传入的数据非常大,这个函数就可能运行很长时间。我想设置让这个函数最多运行10秒钟。如果10秒还没有运行完成,就报错。应该怎么办呢?

如果你的电脑操作系统是 Linux 或者 macOS,那么 可以使用 signal 来解决。

在公众号前几天的文章中,我们介绍了使用signal来接管键盘的中断信号,用到的是 signal.SIGINT 。今天我们要用到的是 signal.SIGALRM

首先我们来看看这个信号的使用方法:

import time
import signal
def handler(signum, _):
  print('定时到!')
  raise Exception('定时到了!')
def clac_statistic(datas):
  time.sleep(100)
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
clac_statistic('xxx')

运行效果如下图所示:

在 Linux/Mac 下为Python函数添加超时时间的方法

首先绑定 signal.SIGALRM 事件到 handler 函数中,然后使用 signal.alarm(10) 延迟10秒发送一个信号。10秒到了以后,函数 handler 被运行。在函数中抛出了一个异常,导致程序结束。 clac_statistic 函数原本要运行100秒,但是在10秒以后就停止了,从而实现了函数的超时功能。

基于以上原理,我们实现一个装饰器,来简化为不同函数设置超时功能:

import time
import signal
class FuncTimeoutException(Exception):
  pass
def handler(signum, _):
  raise FuncTimeoutException('函数定时到了!')
def func_timeout(times=0):
  def decorator(func):
    if not times:
      return func
    def wraps(*args, **kwargs):
      signal.alarm(times)
      result = func(*args, **kwargs)
      signal.alarm(0) # 函数提前运行完成,取消信号
      return result
    return wraps
  return decorator
signal.signal(signal.SIGALRM, handler)

我们来试一试测试一下这个函数超时装饰器。首先测试函数的运行时间小于超时时间时,程序正常运行没有问题:

在 Linux/Mac 下为Python函数添加超时时间的方法

再来测试一下函数运行时间超过超时时间的情况:

在 Linux/Mac 下为Python函数添加超时时间的方法

正常抛出 FuncTimeoutException 异常。

那我们在实际使用中,可以使用 try...except FuncTimeoutException 捕获这个异常,然后实现自定义的处理流程,例如:

try:
  clac_statistic(100)
except FuncTimeException:
  print('该函数运行超时,运行自定义的处理流程')

当然你如果想直接跳过这个异常也没问题:

import contextlib:
with contextlib.supress(FuncTimeException):
  clac_statistic(100)

总结

以上所述是小编给大家介绍的在 Linux/Mac 下为Python函数添加超时时间的方法,希望对大家有所帮助,也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python实现的数据结构与算法之队列详解
Apr 22 Python
Python下载指定页面上图片的方法
May 12 Python
详解MySQL数据类型int(M)中M的含义
Nov 20 Python
Python删除Java源文件中全部注释的实现方法
Aug 30 Python
python字符串string的内置方法实例详解
May 14 Python
Django使用Mysql数据库已经存在的数据表方法
May 27 Python
Python交互环境下实现输入代码
Jun 22 Python
一篇文章弄懂Python中的可迭代对象、迭代器和生成器
Aug 12 Python
详解Python3 pandas.merge用法
Sep 05 Python
TensorBoard 计算图的查看方式
Feb 15 Python
Python+pyftpdlib实现局域网文件互传
Aug 24 Python
详解Go语言运用广度优先搜索走迷宫
Jun 23 Python
Python os模块常用方法和属性总结
Feb 20 #Python
Python requests获取网页常用方法解析
Feb 20 #Python
pytorch实现保证每次运行使用的随机数都相同
Feb 20 #Python
Python argparse模块使用方法解析
Feb 20 #Python
浅谈pytorch torch.backends.cudnn设置作用
Feb 20 #Python
Python sqlite3查询操作过程解析
Feb 20 #Python
python利用datetime模块计算程序运行时间问题
Feb 20 #Python
You might like
PHP使用array_fill定义多维数组的方法
2015/03/18 PHP
php冒泡排序与快速排序实例详解
2015/12/07 PHP
Yii框架函数简单用法分析
2019/09/09 PHP
JS解析XML的实现代码
2009/11/12 Javascript
jQuery窗口、文档、网页各种高度的精确理解
2014/07/02 Javascript
JS常用函数使用指南
2014/11/23 Javascript
js中scrollTop()方法和scroll()方法用法示例
2016/10/03 Javascript
JS基于正则截取替换特定字符之间字符串操作示例
2017/02/03 Javascript
Bootstrap Table使用整理(一)
2017/06/09 Javascript
JS笛卡尔积算法与多重数组笛卡尔积实现方法示例
2017/12/01 Javascript
Element UI 自定义正则表达式验证方法
2018/09/04 Javascript
运用js实现图层拖拽的功能
2019/05/24 Javascript
优雅的使用javascript递归画一棵结构树示例代码
2019/09/22 Javascript
JS求解两数之和算法详解
2020/04/28 Javascript
Python 面向对象 成员的访问约束
2008/12/23 Python
python异步任务队列示例
2014/04/01 Python
Python实现的tab文件操作类分享
2014/11/20 Python
用Python的pandas框架操作Excel文件中的数据教程
2015/03/31 Python
编写Python小程序来统计测试脚本的关键字
2016/03/12 Python
Python函数式编程
2017/07/20 Python
TensorFlow实现Batch Normalization
2018/03/08 Python
python获取当前目录路径和上级路径的实例
2018/04/26 Python
Python3转换html到pdf的不同解决方案
2019/03/11 Python
pybind11在Windows下的使用教程
2019/07/04 Python
Python实现一个带权无回置随机抽选函数的方法
2019/07/24 Python
python脚本执行CMD命令并返回结果的例子
2019/08/14 Python
python字典的值可以修改吗
2020/06/29 Python
斯图尔特·韦茨曼鞋加拿大官网:Stuart Weitzman加拿大
2019/10/13 全球购物
客户代表实习人员自我鉴定
2013/09/27 职场文书
专家推荐信模板
2014/05/09 职场文书
2014年乡镇安全生产工作总结
2014/12/02 职场文书
MBA推荐信怎么写
2015/03/25 职场文书
话题作文之学会尊重
2019/12/16 职场文书
用python开发一款操作MySQL的小工具
2021/05/12 Python
Python下opencv库的安装过程及问题汇总
2021/06/11 Python
Python中rapidjson参数校验实现
2021/07/25 Python