如何在Windows平台上强制超时Python中的函数

3

我想要做的就是如果函数在规定时间内没有返回,就强制停止它。

这一切都始于 urllib2 支持 urlopen 的超时设置,但不支持读取���分的超时设置,导致我的程序崩溃。更改套接字的 defaulttimeout 也无效。使用 signal.sigalrm 也无效。我不能切换到 requests,因为那样我需要重写和测试很多代码。

我不想让线程运行该函数并在超时后终止线程,我想直接控制函数的超时。有什么好的方法吗?

2个回答

0

我喜欢在我的项目中使用David的类这里。我发现它非常有效,并且我喜欢它通过装饰器提供了一种简单的方式来实现现有代码。例如:

# Timeout after 30 seconds
@timeout(30)
def your_function():
    ...

注意:这段代码不是线程安全的!如果您正在使用多线程,信号将被随机线程捕获。但对于单线程程序来说,这是最简单的解决方案。


4
很遗憾,我正在使用Windows操作系统,因此不支持signal.sigalrm。你指出的代码使用了signal.sigalrm。 - Eric Cartman

0

是的,可以在Windows中完成而不需要信号,并且在其他操作系统中也可以工作。这是使用线程而不是运行函数来引发超时信号。逻辑是创建一个新线程并等待一定时间,然后使用_thread(在Python3中)或线程(在Python2中)引发异常。如果发生任何异常,此异常将在主线程中抛出,并且with块将退出。

import threading
import _thread   # import thread in python2
class timeout():
  def __init__(self, time):
    self.time= time
    self.exit=False

  def __enter__(self):
    threading.Thread(target=self.callme).start()

  def callme(self):
    time.sleep(self.time)
    if self.exit==False:
       _thread.interrupt_main()  # use thread instead of _thread in python2
  def __exit__(self, a, b, c):
       self.exit=True

使用示例:

with timeout(2):
    func()

在 with 块中的程序应该在 2 秒内退出,否则将在 2 秒后退出。


请勿在您的代码中使用此内容,我认为它不是线程安全的,在我的情况下整个程序将退出。 - greendino

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接