在 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')

运行效果如下图所示:

在 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函数添加超时时间的方法网站的支持!

来源:https://juejin.im/post/5e4d134c518825490b647a66

标签:python,函数,超时,时间
0
投稿

猜你喜欢

  • PyCharm添加Anaconda中的虚拟环境Python解释器出现Conda executable is not found错误解决

    2022-02-24 23:51:03
  • 三层级联动的日期选择下拉框javascript源码

    2013-08-15 16:50:40
  • Python使用QQ邮箱发送Email的方法实例

    2021-03-25 11:33:57
  • python猜数字小游戏实现代码

    2022-04-20 19:01:43
  • Jupyter notebook在mac:linux上的配置和远程访问的方法

    2023-06-20 06:11:01
  • tensorflow图像裁剪进行数据增强操作

    2023-06-23 14:33:20
  • DataReader深入解析:持续更新

    2023-07-11 06:24:08
  • 关于字体的一些思考

    2008-03-03 12:53:00
  • 利用Python找回微信撤回信息

    2022-11-21 22:34:03
  • Python中关于Sequence切片的下标问题详解

    2021-05-30 22:49:47
  • pytorch 液态算法实现瘦脸效果

    2021-12-05 19:28:17
  • SQL Server 作业的备份(备份作业非备份数据库)

    2024-01-17 02:43:44
  • Oracle中查询本月星期5的所有日期列表的语句

    2012-07-11 16:13:21
  • SQL Server 远程更新目标表数据的存储过程

    2024-01-21 07:38:04
  • Asp 操作Access数据库时出现死锁.ldb的解决方法

    2011-03-29 10:49:00
  • python3 循环读取excel文件并写入json操作

    2022-11-07 15:40:11
  • php隐藏IP地址后两位显示为星号的方法

    2023-08-16 13:05:17
  • Python colorama 彩色打印实现代码

    2022-10-03 22:32:28
  • ASP与MySQL的连接[图文教程]

    2010-03-14 11:21:00
  • Pytest 自动化测试框架的使用

    2022-11-12 16:47:46
  • asp之家 网络编程 m.aspxhome.com