在 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字典序问题实例
Sep 26 Python
Python实现数据库编程方法详解
Jun 09 Python
Python使用Mechanize模块编写爬虫的要点解析
Mar 31 Python
使用python读取csv文件快速插入数据库的实例
Jun 21 Python
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
Apr 03 Python
浅谈python多进程共享变量Value的使用tips
Jul 16 Python
Django实现发送邮件功能
Jul 18 Python
python连接PostgreSQL数据库的过程详解
Sep 18 Python
Python Tornado批量上传图片并显示功能
Mar 26 Python
Django更新models数据库结构步骤
Apr 01 Python
python基于win32api实现键盘输入
Dec 09 Python
python 爬取京东指定商品评论并进行情感分析
May 27 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 laravel中的多对多关系实例详解
2017/06/07 PHP
Laravel中Facade的加载过程与原理详解
2017/09/22 PHP
JS实现双击编辑可修改状态的方法
2015/08/14 Javascript
jquery特效 点击展示与隐藏全文
2015/12/09 Javascript
jquery siblings获取同辈元素用法实例分析
2016/07/25 Javascript
微信小程序 slider 详解及实例代码
2017/01/10 Javascript
初探nodeJS
2017/01/24 NodeJs
开发用到的js封装方法(20种)
2018/10/12 Javascript
微信小程序调用微信支付接口的实现方法
2019/04/29 Javascript
JS实现的贪吃蛇游戏案例详解
2019/05/01 Javascript
微信小程序下拉框搜索功能的实现方法
2019/07/31 Javascript
[10:18]2018DOTA2国际邀请赛寻真——找回自信的TNCPredator
2018/08/13 DOTA
Python 检查数组元素是否存在类似PHP isset()方法
2014/10/14 Python
python将字符串转换成数组的方法
2015/04/29 Python
Python求两个文本文件以行为单位的交集、并集与差集的方法
2015/06/17 Python
python对配置文件.ini进行增删改查操作的方法示例
2017/07/28 Python
Python 多进程并发操作中进程池Pool的实例
2017/11/01 Python
hmac模块生成加入了密钥的消息摘要详解
2018/01/11 Python
python实现邮件发送功能
2019/08/10 Python
Pytorch之finetune使用详解
2020/01/18 Python
解决pycharm同一目录下无法import其他文件
2020/02/12 Python
详解css3 Transition属性(平滑过渡菜单栏案例)
2017/09/05 HTML / CSS
Shopee印度尼西亚:东南亚与台湾市场最大电商平台
2018/06/17 全球购物
Hunkemöller西班牙:欧洲最大的内衣连锁店
2018/08/15 全球购物
美国隐形眼镜零售商:LensPure
2019/03/10 全球购物
eDreams德国:南欧领先的在线旅游公司
2020/12/07 全球购物
会计岗位职责范本
2014/03/07 职场文书
公司表扬稿范文
2015/05/05 职场文书
2015年挂职锻炼个人总结
2015/10/22 职场文书
公司年会晚会开幕词
2019/04/02 职场文书
python用字节处理文件实例讲解
2021/04/13 Python
python如何进行基准测试
2021/04/26 Python
JDBC连接的六步实例代码(与mysql连接)
2021/05/12 MySQL
Spring实现内置监听器
2021/07/09 Java/Android
Python超详细分步解析随机漫步
2022/03/17 Python
JS精髓原型链继承及构造函数继承问题纠正
2022/06/16 Javascript