在 Linux/Mac 下为Python函数添加超时时间的方法
作者:青南 发布时间:2023-08-17 14:27:12
我们在使用 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')
运行效果如下图所示:
首先绑定 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)
我们来试一试测试一下这个函数超时装饰器。首先测试函数的运行时间小于超时时间时,程序正常运行没有问题:
再来测试一下函数运行时间超过超时时间的情况:
正常抛出 FuncTimeoutException
异常。
那我们在实际使用中,可以使用 try...except FuncTimeoutException
捕获这个异常,然后实现自定义的处理流程,例如:
try:
clac_statistic(100)
except FuncTimeException:
print('该函数运行超时,运行自定义的处理流程')
当然你如果想直接跳过这个异常也没问题:
import contextlib:
with contextlib.supress(FuncTimeException):
clac_statistic(100)
总结
以上所述是小编给大家介绍的在 Linux/Mac 下为Python函数添加超时时间的方法网站的支持!
来源:https://juejin.im/post/5e4d134c518825490b647a66


猜你喜欢
- 因时间问题不可能一次写的很多,但我们会经常更新,方便大家。希望学习编程的朋友不要因为从网站复制了代码,而不能正常的运行而放弃。其实老鸟也是经
- Go pongo2 教程展示了如何使用 pongo2 模板引擎在 Golang 中使用模板。模板引擎是一个库,旨在将模板与数据结合起来以生成
- 如何开始 C#学习过程中有一集讲的是如何查看类图,看完视频后自己就学习如何在VS 2019中查看类图,但是找了好长时间都没有找到查看类图这
- 本文实例讲述了php可应用于面包屑导航的迭代寻找家谱树实现方法。分享给大家供大家参考。具体实现方法如下:<?phpecho "
- Tqdm库比较常用,用于显示进度条。简单用法:from tqdm import tqdmfor i in tqdm(range(2)):
- SQL Server查询速度慢的原因有很,常见的有以下几种:1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)2、I/
- 1.忍受 * 第一种解决办法,很简单,无他,不管他,没有读到也没事。这时业务不需要任何改造,你好,我好,她也好~如果业务对于数据一致性要求不高
- 所谓“分块”,顾名思义,就是将数据集分成几块进行读取,比如有105条数据,一次读取10条,读取11次
- 代理的使用场景编写爬虫代码的程序员,永远绕不开就是使用代理,在编码过程中,你会碰到如下情形:网络不好,需要代理;目标站点国内访问不了,需要代
- 前言本博客默认读者对神经网络与Tensorflow有一定了解,对其中的一些术语不再做具体解释。并且本博客主要以图片数据为例进行介绍,如有错误
- 在进行数据库的查询时,会经常遇到这样的情况:例如想在一个用户数据库中查询他的用户名和他的密码,但恰好该用户使用的名字和密码中有特殊的字符,例
- '$.browser.msie' 为空或不是对象,这个是jQuery错误出现这个错误,是因为升级了jQuery版本,从1.9
- 写这篇文章的时候,还真不知道如何取名,也不知道这个该如何将其归类。这个是同事遇到的一个案例,案例比较复杂,这里抽丝剥茧,仅仅构造一个简单的案
- 如:$str="php如何将字 符串中322的字母数字sf f45d和中文_分割?";按数字或字母分割。$str = &
- js调试工具推荐firefox的firebug插件能够给js设置断点执行能够运行时修改css样式查看dom模型等☆IE8自带的develop
- 一、前言说明今天看到微信群里一道六年级数学题,如下图,求阴影部分面积看起来似乎并不是很难,可是博主添加各种辅助线,写各种方法都没出来,不得已
- 一、MySQL删除外键格式:alter table 表名 drop foreign key 外键名;表名就是有外键存在的那个表。外键名可以通
- 本文实例为大家分享了python实现名片管理系统源代码,供大家参考,具体内容如下import osdef print_menu(): pri
- 问:怎样实现ORACLE中用一条SQL实现其它进制到十进制的转换?答:具体示例如下:-----二进制转换十进制---------------
- PDOStatement::bindColumnPDOStatement::bindColumn — 绑定一列到一个 PHP 变量(PHP