使用Python中的信号超时
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Python中的信号超时相关的知识,希望对你有一定的参考价值。
我试图阻止我的UDP客户端程序在服务器丢失数据包的情况下永远等待。我想用信号来实现这个。我的代码是:
def handler(signum):
raise TimeoutException("Timeout occured!")
signal.signal(signal.SIGALRM, sig_alarm)
sock.sendto(data,serv)
signal.alarm(5)
try:
received_time, servaddr = sock.recvfrom(size)
except TimeoutException:
print "timeout"
signal.alarm(0)
在远程服务器关闭的实例中运行此代码时,出现以下错误:
global name 'TimeoutException' is not defined
我假设程序没有“看到”我的处理程序。可能导致什么呢?
TimeoutException
或Python 2标准库中没有Python 3异常类型。在Python 3.3及更新版本中,有一个TimeoutError
类型,当操作系统调用在系统中超时时(相应于errno
被设置为ETIMEDOUT
值)。但是,我不建议您自己提高此值,因为它的特定意图是响应操作系统返回的超时而引发。
Correct use of signal.signal
在您的comment中,在定义自定义超时异常类型后,您指示出现进一步的错误:handler() takes exactly 1 argument (2 given)
。
发生这种情况是因为您的信号处理程序不遵循signal
package(Python 3的那些文档,但与Python 2相同)所期望的信号处理函数的定义:
signal.signal(signum, handler)
将信号signalnum的处理程序设置为函数处理程序...使用两个参数调用处理程序:信号编号和当前堆栈帧
要解决此问题,请调整自定义信号处理程序的定义,以将堆栈帧作为第二个参数接收。你需要在函数调用中接受这个,正如标准库所期望的那样,但你不需要对传入的值做任何事情。
def handler(signum, frame):
raise TimeoutException("Timeout occurred!")
Better way? Use socket.settimeout
在socket
library中有内置的支持,你要完成的是:套接字对象的settimeout
method。我建议在你的代码中使用它,而不是试图重新发明轮子;它在抽象实现细节的同时声明了意图,并且有一个内置的异常类型(socket.timeout
),您可以捕获它来确定何时发生超时。
使用此方法,您只需在进行阻塞调用之前在套接字上调用socket.settimeout(5)
,这可能会超时。您还可以在打开应用程序中的第一个套接字之前使用socket.setdefaulttimeout
在所有套接字上设置默认超时。
TimeoutException
最初来自哪里?
显然,你对它的使用可能源于任何地方。但是,我注意到Selenium中有一个TimeoutException
,它是一个广泛使用的Python库,用于自动化浏览器。它被广泛使用,与Selenium相关的示例/ Q&A很常见,所以如果您找到文档或示例使您认为这是标准库中存在的异常类型,我不会感到惊讶,而它实际上是特定于那个图书馆。似乎与Selenium相关的任何内容都不适用于您目前的用例。
对于此错误:global name 'TimeoutException' is not defined
表示您必须声明自定义异常..这样做的简单方法是将其添加到您的代码中:
class TimeoutException(Exception):
pass
有一点需要注意的是,selenium有一个名为TimeoutException
的异常,它不是标准库中存在的异常类型,但特定于selenium库:
from selenium.common.exceptions import TimeoutException
最后你会遇到另一个错误,因为你的信号处理程序必须接收堆栈帧作为第二个参数(使用两个参数调用处理程序:信号编号和当前堆栈帧):
def handler(signum, frame):
raise TimeoutException("Timeout occurred!")
请阅读文档minimal example program中的以下示例
以上是关于使用Python中的信号超时的主要内容,如果未能解决你的问题,请参考以下文章