当前位置: 首页 > 编程笔记 >

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

巢睿
2023-03-14
本文向大家介绍在 Linux/Mac 下为Python函数添加超时时间的方法,包括了在 Linux/Mac 下为Python函数添加超时时间的方法的使用技巧和注意事项,需要的朋友参考一下

我们在使用 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函数添加超时时间的方法,希望对大家有所帮助,也非常感谢大家对小牛知识库网站的支持!

 类似资料:
  • 问题内容: 过去,已经进行了许多尝试以在Python中添加超时功能,以便在指定的时间限制到期时,等待的代码可以继续运行。不幸的是,以前的配方要么允许正在运行的功能继续运行并消耗资源,要么使用特定于平台的线程终止方法终止该功能。该Wiki的目的是针对这个问题开发跨平台的答案,许多程序员必须针对各种编程项目解决该问题。 编辑: 这段代码是为Python 3.x编写的,并非为装饰类方法而设计。该模块并非

  • 问题内容: 我将csv文件读入pandas数据框,得到以下信息: 无论是和列有100个元素。我想将Hour的相应元素添加到TDate。 我尝试了以下方法: 但是我得到了错误,因为td似乎没有将array作为参数。如何将的每个元素添加到的相应元素中。 问题答案: 我想你可以添加到列列转换有:

  • 问题内容: 我正在Python中调用一个函数,该函数可能会停滞并迫使我重新启动脚本。 如何调用该函数或将其包装在其中,以便如果花费的时间超过5秒,脚本将取消该函数并执行其他操作? 问题答案: 如果在上运行,则可以使用信号包: 调用后10秒钟,将调用处理程序。这引发了一个异常,你可以从常规Python代码中拦截该异常。 该模块不能很好地与线程配合使用(但是,谁可以呢?) 请注意,由于发生超时时会引发

  • 问题内容: 我想要在两种系统上的两者之间进行转换的多种方法。我正在寻找一种快速简便的方法来做到这一点。 我想要Python方式,excel,openoffice calc方式,访问方式,命令行方式。您做的任何其他方式也将很好。换种方式(从Windows到Linux)也很好 我从某些脚本中获得的输出包括自1970年以来的时间(以秒为单位),但我想转换为Windows时间。这样,当将其导入数据库时​​

  • 本文向大家介绍php下载文件超时时间的设置方法,包括了php下载文件超时时间的设置方法的使用技巧和注意事项,需要的朋友参考一下 使用curl 可以使用curl自己实现一个curl_file_get_contents函数 超时的错误输出类似下边这样 Curl error: Operation timed out after 991 milliseconds with 3706978 out of 1

  • 问题内容: 我正在开发一个支持Google两步验证的应用程序。此应用程序还支持“可信任此设备30天”的功能。 我使用数据库保存所有这些信息,例如IP地址和到期时间。现在,当我填写时间戳以将当前时间增加30天时,它将比当前时间早的时间戳插入数据库中。 例如:当前时间= 。现在,当我加上30天(毫秒)时,得出的日期不是30天,而是大约19天。 问题答案: 此问题与32位整数溢出有关。由于整数的最大值为