在 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 相关文章推荐
python3 实现的人人影视网站自动签到
Jun 19 Python
Python Socket使用实例
Dec 18 Python
Python cookbook(数据结构与算法)将多个映射合并为单个映射的方法
Apr 19 Python
对Python中Iterator和Iterable的区别详解
Oct 18 Python
在Django的View中使用asyncio的方法
Jul 12 Python
对Python生成器、装饰器、递归的使用详解
Jul 19 Python
使用pandas的box_plot去除异常值
Dec 10 Python
Python模块相关知识点小结
Mar 09 Python
VSCode配合pipenv搞定虚拟环境的实现方法
May 17 Python
Python如何使用input函数获取输入
Aug 06 Python
Python基于pillow库实现生成图片水印
Sep 14 Python
快速解决pymongo操作mongodb的时区问题
Dec 05 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代码把全角数字转为半角数字
2007/12/10 PHP
用php过滤危险html代码的函数
2008/07/22 PHP
PHP Ajax中文乱码问题解决方法
2009/02/27 PHP
如何设置mysql允许外网访问
2013/06/04 PHP
Yii配置文件用法详解
2014/12/04 PHP
PHP 常用的header头部定义汇总
2015/06/19 PHP
详解PHP中websocket的使用方法
2016/09/15 PHP
JQUERY 对象与DOM对象之两者相互间的转换
2009/04/27 Javascript
jQuery1.6 使用方法一
2011/11/23 Javascript
jquery如何实现在加载完iframe的内容后再进行操作
2013/09/10 Javascript
原生js编写设为首页兼容ie、火狐和谷歌
2014/06/05 Javascript
javascript将异步校验表单改写为同步表单
2015/01/27 Javascript
JavaScript中最容易混淆的作用域、提升、闭包知识详解(推荐)
2016/09/05 Javascript
微信小程序 textarea 组件详解及简单实例
2017/01/10 Javascript
Angular4自制一个市县二级联动组件示例
2017/11/21 Javascript
Cookbook组件形式:优化 Vue 组件的运行时性能
2018/11/25 Javascript
vue单页面在微信下只能分享落地页的解决方案
2019/04/15 Javascript
微信小程序npm引入vant-weapp的踩坑记录
2019/08/01 Javascript
[16:21]教你分分钟做大人:圣堂刺客
2014/12/03 DOTA
[10:21]2018DOTA2国际邀请赛寻真——Winstrike
2018/08/11 DOTA
玩转python爬虫之URLError异常处理
2016/02/17 Python
python批量制作雷达图的实现方法
2016/07/26 Python
使用python调用zxing库生成二维码图片详解
2017/01/10 Python
python好玩的项目—色情图片识别代码分享
2017/11/07 Python
Python中optparser库用法实例详解
2018/01/26 Python
python使用tensorflow保存、加载和使用模型的方法
2018/01/31 Python
python实现列表中最大最小值输出的示例
2019/07/09 Python
西门豹教学反思
2014/02/04 职场文书
健康家庭事迹材料
2014/05/02 职场文书
数控专业毕业生求职信
2014/06/12 职场文书
师范类求职信
2014/06/21 职场文书
见习报告的格式
2014/11/04 职场文书
傲慢与偏见电影观后感
2015/06/10 职场文书
交通安全教育主题班会
2015/08/12 职场文书
JavaScript 反射学习技巧
2021/10/16 Javascript
Promise静态四兄弟实现示例详解
2022/07/07 Javascript