在 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 相关文章推荐
多线程爬虫批量下载pcgame图片url 保存为xml的实现代码
Jan 17 Python
Python编程之event对象的用法实例分析
Mar 23 Python
Python数据结构与算法之常见的分配排序法示例【桶排序与基数排序】
Dec 15 Python
Python下载网络文本数据到本地内存的四种实现方法示例
Feb 05 Python
python中将一个全部为int的list 转化为str的list方法
Apr 09 Python
PyCharm+PySpark远程调试的环境配置的方法
Nov 29 Python
python远程调用rpc模块xmlrpclib的方法
Jan 11 Python
Python实现合并excel表格的方法分析
Apr 13 Python
python通过opencv实现图片裁剪原理解析
Jan 19 Python
python正则表达式实例代码
Mar 03 Python
Django中和时区相关的安全问题详解
Oct 12 Python
Appium+Python实现简单的自动化登录测试的实现
Jan 26 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
骨王战斗力在公会成员中排不进前五,却当选了会长,原因竟是这样
2020/03/02 日漫
php入门教程 精简版
2009/12/13 PHP
php 文章采集正则代码
2009/12/28 PHP
PHP数组循环操作详细介绍 附实例代码
2013/02/03 PHP
php中如何判断一个网页请求是ajax请求还是普通请求
2013/08/10 PHP
ThinkPHP之A方法实例讲解
2014/06/20 PHP
php上传文件常见问题总结
2015/02/03 PHP
php获取从百度、谷歌等搜索引擎进入网站关键词的方法
2015/07/08 PHP
thinkPHP微信分享接口JSSDK用法实例
2017/07/07 PHP
实例讲解PHP页面静态化
2018/02/05 PHP
JQuery index()方法使用代码
2010/06/02 Javascript
JS 获取滚动条高度示例代码
2013/10/24 Javascript
jquery 鼠标滑动显示详情应用示例
2014/01/24 Javascript
js表单验证实例讲解
2016/03/31 Javascript
HTML5 canvas 9绘制图片实例详解
2016/09/06 Javascript
canvas绘制多边形
2017/02/24 Javascript
使用Browserify来实现CommonJS的浏览器加载方法
2017/05/14 Javascript
JS实现提交表单前的数字及邮箱校检功能
2017/11/13 Javascript
如何解决.vue文件url引用文件的问题
2019/01/18 Javascript
vue写h5页面的方法总结
2019/02/12 Javascript
JS中的函数与对象的创建方式
2019/05/12 Javascript
[02:08]2014DOTA2国际邀请赛 430专访:力争取得小组前二
2014/07/11 DOTA
[02:03]《现实生活中的DOTA2》—林书豪&DOTA2职业选手出演短片
2015/08/18 DOTA
Python脚本实现代码行数统计代码分享
2015/03/10 Python
python实现逐个读取txt字符并修改
2018/12/24 Python
简单了解Python3里的一些新特性
2019/07/13 Python
python MultipartEncoder传输zip文件实例
2020/04/07 Python
共产党员公开承诺书
2014/03/25 职场文书
保护动物倡议书
2014/04/15 职场文书
庆元旦活动总结
2014/07/09 职场文书
谢师宴家长答谢词
2015/09/30 职场文书
银行岗位培训心得体会
2016/01/09 职场文书
Django drf请求模块源码解析
2021/06/08 Python
SQL之各种join小结详细讲解
2021/08/04 MySQL
Java实现带图形界面的聊天程序
2022/06/10 Java/Android
Mysql数据库group by原理详解
2022/07/07 MySQL