【问题标题】:Python requests sometimes freezesPython 请求有时会冻结
【发布时间】:2016-05-19 10:33:51
【问题描述】:

我有一个 Python 程序,它通过 requests 包为每个轮询使用不同的线程并行发送几个(大约 5-6 个)长轮询请求。我意识到我的一些线程有时会冻结。发生这种情况时,我发送请求的服务器没有收到请求。我还为请求设置了超时,但它不起作用。

try:
    print("This line prints")
    response = requests.head(poll_request_url, timeout=180)
    print("This line does not print when freeze occurs")
except ReadTimeout:
    print("Request exception.")
except RequestException as e:
    print("Request exception.")
except Exception:
    print("Unknown exception.")
print("This line does not print either when freeze occurs.")

我在带有 Raspbian OS 的 Raspberry Pi 2 硬件上执行此操作。

当我使用 Python 2.7 时,我使用了相同的程序没有问题。最近我切换到 Python 3.5。我使用 2.8.1 和 2.9.1 的两个请求版本进行了测试。

这个问题发生的频率不是很高,但每天在不同的线程上发生 2-3 次。

可能是什么问题?我该如何调试?

编辑:通过更新 Linux 内核解决了这个问题。

【问题讨论】:

    标签: python multithreading python-requests long-polling


    【解决方案1】:

    根据文档:

    http://docs.python-requests.org/en/master/user/quickstart/#timeouts

    当超时发生时,它应该抛出一个Timeout 异常。这意味着该行:

    print("This line does not print when freeze occurs")
    

    永远不会被称为超时。

    你发现异常了吗?还是有其他例外?可能是它的超时时间很好,但你只是没有看到这一点。也许尝试这样的事情:

    try:
        response = requests.head(poll_request_url, timeout=180)
    except requests.exceptions.Timeout:
        print("Timeout occurred")
    

    所以你可以看看是不是这样。

    编辑:可能是“连接”步骤未正确超时。可能是“连接”步骤的大超时值以某种方式搞砸了。也许尝试为此设置更短的超时时间(如此处所述):

    http://docs.python-requests.org/en/master/user/advanced/#timeouts

    例如

    response = requests.head(poll_request_url, timeout=(3, 180))
    

    不知道这可能是某种 DNS 查找问题?也许看看硬编码 IP 是否会出现同样的问题?

    【讨论】:

    • 我正在捕获包括超时在内的所有异常,并且当发生超时时,它会成功捕获异常。当超时没有发生并且发生冻结时,该行永远不会执行并且不会引发异常。
    • 我在代码中添加了更多上下文以反映异常处理。
    • 这一定是在“连接”步骤期间未能超时 - 正如您所说的,您从未在服务器上收到请求。
    • 编辑连接超时建议
    • @old-ufo 是的 Linux 内核。如果我没记错的话,我使用 rpi-update 来更新内核并解决了问题。但在此之前,请绝对确保问题不是因为其他原因,例如代码中的竞争条件。在我们确定这是内核问题之前,我们消除了所有可能性,并且花了我们数周时间。
    【解决方案2】:

    使用计时器解决了我的问题(来自线程导入计时器)。如果接下来 10 秒没有结果 - 重复,如果接下来 10 秒没有结果 - 打印“错误”并继续。如果请求冻结,则无法使用 if 语句监视计时器状态,但可以通过 while 循环进行,如果结果正常则添加时间 (Python: Run code every n seconds and restart timer on condition)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-12
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 2017-10-16
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多