Linux超时时间为0,在 Linux/Mac 下为Python函数添加超时时间

在 Linux/Mac 下为Python函数添加超时时间

收录于话题

#你不知道的 Python

71个

7bd4745391b5484ff8df38766d9118de.png

摄影:产品经理

产品经理亲自下厨

我们在使用 requests 这类网络请求第三方库时,可以看到它有一个参数叫做timeout,就是指在网络请求发出开始计算,如果超过 timeout 还没有收到返回,就抛出超时异常。(当然存在特殊情况timeout 会失效,请看Timeouts and cancellation for humans*[1] 这篇文章中作者的举例,我们不考虑这种特殊情况)。

但大家有没有考虑过,如何为普通的函数设置超时时间?特别是在运行一些数据处理、AI 相关的代码时,某个函数可能会运行很长时间,我们想实现,在函数运行超过特定的时间时,自动报错。

例如有这样一个场景,我写了一个函数calc_statistic(datas),根据用户传入的数据计算某个值。但如果用户传入的数据非常大,这个函数就可能运行很长时间。我想设置让这个函数最多运行10秒钟。如果10秒还没有运行完成,就报错。应该怎么办呢?

如果你的电脑操作系统是 Linux 或者 macOS,那么 可以使用 signal 来解决。

在公众号前几天的文章中,我们介绍了使用signal来接管键盘的中断信号:《一日一技:在 Python 中接管键盘中断信号》,用到的是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')

运行效果如下图所示:

2dd02b160c3c016b3a11cc6e87df155d.png

首先绑定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)

我们来试一试测试一下这个函数超时装饰器。首先测试函数的运行时间小于超时时间时,程序正常运行没有问题:

edfcc169752b19226b921eff7884793e.png

再来测试一下函数运行时间超过超时时间的情况:

433d0e727251f2554905cce71beb2ff9.png

正常抛出FuncTimeoutException异常。

那我们在实际使用中,可以使用try...except FuncTimeoutException捕获这个异常,然后实现自定义的处理流程,例如:

try:

clac_statistic(100)

except FuncTimeException:

print('该函数运行超时,运行自定义的处理流程')

当然你如果想直接跳过这个异常也没问题,参考《一日一技:不使用 try...except 掩盖一些已知异常》:

import contextlib:

with contextlib.supress(FuncTimeException):

clac_statistic(100)

参考资料

kingname

攒钱给产品经理买房。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值