在 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实现面向对像的ASP程序实例
Nov 10 Python
用Python代码来解图片迷宫的方法整理
Apr 02 Python
用Pygal绘制直方图代码示例
Dec 07 Python
python提取具有某种特定字符串的行数据方法
Dec 11 Python
Python3实现的简单三级菜单功能示例
Mar 12 Python
Pandas之MultiIndex对象的示例详解
Jun 25 Python
Python 实现文件读写、坐标寻址、查找替换功能
Sep 11 Python
ubuntu上安装python的实例方法
Sep 30 Python
python实现修改固定模式的字符串内容操作示例
Dec 30 Python
Python实现计算图像RGB均值方式
Jun 04 Python
Django通过设置CORS解决跨域问题
Nov 26 Python
python3处理word文档实例分析
Dec 01 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学习之数组的定义和填充
2011/04/17 PHP
关于php mvc开发模式的感想
2011/06/28 PHP
10个实用的PHP正则表达式汇总
2014/10/23 PHP
PHP基于反射机制实现插件的可插拔设计详解
2016/11/10 PHP
Flash+XML滚动新闻代码 无图片 附源码下载
2007/11/22 Javascript
JavaScript开发规范要求(规范化代码)
2010/08/16 Javascript
解析John Resig Simple JavaScript Inheritance代码
2012/12/03 Javascript
两种常用的javascript数组去重方法思路及代码
2013/03/26 Javascript
jqGrid日期格式的判断示例代码(开始日期与结束日期)
2013/11/08 Javascript
Jquery实现地铁线路指示灯提示牌效果的方法
2015/03/02 Javascript
基于Bootstrap表单验证功能
2017/11/17 Javascript
Vue render深入开发讲解
2018/04/13 Javascript
JavaScript引用类型Date常见用法实例分析
2018/08/08 Javascript
解决vue select当前value没有更新到vue对象属性的问题
2018/08/30 Javascript
Vue表单及表单绑定方法
2018/09/04 Javascript
Node.js npm命令运行node.js脚本的方法
2018/10/10 Javascript
使用webpack4编译并压缩ES6代码的方法示例
2019/04/24 Javascript
详细讲解用Python发送SMTP邮件的教程
2015/04/29 Python
Python中asyncore异步模块的用法及实现httpclient的实例
2016/06/28 Python
Python内存管理方式和垃圾回收算法解析
2017/11/11 Python
Python列表推导式、字典推导式与集合推导式用法实例分析
2018/02/07 Python
python线程安全及多进程多线程实现方法详解
2019/09/27 Python
Python爬虫实现自动登录、签到功能的代码
2020/08/20 Python
英国的知名精品百货公司:House of Fraser(福来德)
2016/08/14 全球购物
雅萌 (YA-MAN) :日本美容家电领域的龙头企业
2017/05/12 全球购物
西班牙在线药店:DosFarma
2020/03/28 全球购物
工商管理专业职业生涯规划
2014/01/01 职场文书
职工趣味运动会方案
2014/02/10 职场文书
关工委先进个人事迹材料
2014/05/23 职场文书
印刷技术专业自荐信
2014/09/18 职场文书
2015年双拥工作总结
2015/04/08 职场文书
烛光里的微笑观后感
2015/06/17 职场文书
2016年基层党支部书记公开承诺书
2016/03/25 职场文书
《追风筝的人》:人心中的成见是座大山,但请不忘初心
2019/11/15 职场文书
js实现上传图片到服务器
2021/04/11 Javascript
QT连接MYSQL数据库的详细步骤
2021/07/07 MySQL