【问题标题】:Detecting hangs with Python urllib2.urlopen使用 Python urllib2.urlopen 检测挂起
【发布时间】:2011-04-06 11:04:06
【问题描述】:

我正在使用Python's urllib2 发送 HTTP 帖子:

import socket, urllib, urllib2

socket.setdefaulttimeout(15)    

postdata = urllib.urlencode({'value1' : 'a string', 'value2' : 'another string'})
headers = {
    'User-Agent': 'Agent',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Accept': 'text/html, */*',
}

try: 
    request = urllib2.Request('http://www.example.com', postData, headers)
    response = urllib2.urlopen(request)
except urllib2.HTTPError, e:
    # Handle here
except urllib2.URLError, e:
    # Handle here
except httplib.HTTPException, e:
    # Handle here

有时网络问题会导致对 urlopen 的调用永远不会返回。我们看到 except 块正确处理了其他错误(包括超时)并调用了 socket.setdefaulttimeout() 但仍然存在 urlopen 永远不会返回的情况。

我知道它永远不会返回,因为我们的实际代码中有一些日志行在之前和之后被调用,当这个问题发生时,只有之前的调用才会被调用并且脚本永远挂起。

检测/处理此问题的最佳方法是什么?

【问题讨论】:

  • 修改默认套接字超时对您不起作用吗?
  • 我和你有同样的问题,你解决了吗?

标签: python sockets networking


【解决方案1】:

您可以使用信号,首先为您的信号设置一个处理程序

import signal
...
def handler(signum, frame):
    print 'Signal handler called with signal', signum
...
signal.signal(signal.SIGALRM, handler)

并在 urlopen 调用之前发出警报

signal.alarm(5)
response = urllib2.urlopen(request)
signal.alarm(0) # Disable the signal

如果警报未禁用(如果 urlopen 永远不会返回),操作系统将在 5 秒(或您希望的时间)后调用处理程序。更多信号模块信息:http://docs.python.org/library/signal.html

【讨论】:

  • ...然后在处理程序中我可以抛出一个异常,该异常将被外部 try/except 块捕获。
  • 这在 Windows 上不起作用(不支持signal.alarm()
  • @Sebastien,here 你可以找到关于 Windows 系统中 signal.alarm() 的讨论
  • 不适用于 Linux。拔下网线并执行。 signal.alarm(5) 被忽略。
  • 嗨@ViktorJoras,我刚刚在ubuntu 18.04.1 中尝试了Python 2.7.15 和3.6.7,它可以工作。也许您应该打开一个新问题,提供有关您的问题的更多详细信息。
猜你喜欢
  • 2011-03-31
  • 2012-04-11
  • 2012-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多