在 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 04 Python
python中in在list和dict中查找效率的对比分析
May 04 Python
python 实现语音聊天机器人的示例代码
Dec 02 Python
python实现浪漫的烟花秀
Jan 30 Python
python导入坐标点的具体操作
May 10 Python
python常用库之NumPy和sklearn入门
Jul 11 Python
python3 反射的四种基本方法解析
Aug 26 Python
8段用于数据清洗Python代码(小结)
Oct 31 Python
python中count函数简单用法
Jan 05 Python
scrapy数据存储在mysql数据库的两种方式(同步和异步)
Feb 18 Python
Django实现将一个字典传到前端显示出来
Apr 03 Python
详解pandas绘制矩阵散点图(scatter_matrix)的方法
Apr 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无限遍历目录示例
2014/02/21 PHP
5 cool javascript apps
2007/03/24 Javascript
JavaScript的9个陷阱及评点分析
2008/05/16 Javascript
NodeJS框架Express的模板视图机制分析
2011/07/19 NodeJs
Javascript 判断是否存在函数的方法
2013/01/03 Javascript
javascript-表格排序(降序/反序)实现介绍(附图)
2013/05/30 Javascript
自定义ExtJS控件之下拉树和下拉表格附源码
2013/10/15 Javascript
两个select多选模式的选项相互移动(示例代码)
2014/01/11 Javascript
原生js和jQuery随意改变div属性style的名称和值
2014/10/22 Javascript
Nodejs学习笔记之Stream模块
2015/01/13 NodeJs
Bootstrap 3.x打印预览背景色与文字显示异常的解决
2016/11/06 Javascript
详解vue数据渲染出现闪烁问题
2017/06/29 Javascript
vue 项目打包通过命令修改 vue-router 模式 修改 API 接口前缀
2018/06/13 Javascript
Vue项目History模式404问题解决方法
2018/10/31 Javascript
Nodejs核心模块之net和http的使用详解
2019/04/02 NodeJs
富文本编辑器vue2-editor实现全屏功能
2019/05/26 Javascript
利用Python中的输入和输出功能进行读取和写入的教程
2015/04/14 Python
Python文件操作之合并文本文件内容示例代码
2017/09/19 Python
Python3中函数参数传递方式实例详解
2019/05/05 Python
PYQT5设置textEdit自动滚屏的方法
2019/06/14 Python
Python中的self用法详解
2019/08/06 Python
python os.path.isfile 的使用误区详解
2019/11/29 Python
用pandas划分数据集实现训练集和测试集
2020/07/20 Python
python时间time模块处理大全
2020/10/25 Python
使用OpenCV实现人脸图像卡通化的示例代码
2021/01/15 Python
浅谈移动端网页图片预加载方案
2018/11/05 HTML / CSS
canvas如何实现多张图片编辑的图片编辑器
2020/03/10 HTML / CSS
Peter Alexander新西兰站:澳大利亚领先的睡衣设计师品牌
2016/12/10 全球购物
澳大利亚儿童和婴儿产品在线商店:Lime Tree Kids
2017/10/05 全球购物
ProForm英国站点:健身房和健身器材网上商店
2019/06/05 全球购物
财务担保书范文
2014/04/02 职场文书
大学学习计划书范文
2014/05/02 职场文书
2015年七七事变78周年纪念活动方案
2015/05/06 职场文书
Python学习之时间包使用教程详解
2022/03/21 Python
Python中request的基本使用解决乱码问题
2022/04/12 Python
nginx rewrite功能使用场景分析
2022/05/30 Servers