【问题标题】:Socket threads hang in timeout block套接字线程在超时块中挂起
【发布时间】:2012-06-15 10:57:34
【问题描述】:

我正在尝试计算从给定套接字接收所有数据所需的时间,所以我使用“with Timeout(5, False)”等待 5 秒的数据,然后保存最后一次接收的时间.但是,当我提供多个线程时,当前的代码只会停滞不前。我想帮助弄清楚为什么它应该超时时才挂起。

#!/usr/bin/env python
import sys
import time
from gevent import socket, Timeout
from gevent.pool import Pool

def calc_wait(website):
    data = ''
    start = stop = time.time()
    sock_buffer = ''

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((website,80))
    s.send('HEAD / HTTP/1.1\n\n')

    with Timeout(5, False):
        while True:
            data = s.recv(1024)
            if data:
                sock_buffer += data
                stop = time.time()

    print ('Recieved {0} bytes in {1} seconds from {2}'
           .format(len(sock_buffer), stop-start, s.getpeername()))

    return 0

if __name__ == "__main__":

    targs = ['google.com', 'yahoo.com', 'bing.com',\
             'tide.com', 'monkey.com', 'python.com',\
             'a.com', 'b.com', 'c.com', 'd.com']

    pool = Pool(10)
    for t in targs:
        pool.spawn(calc_wait, t)
    pool.join()

【问题讨论】:

  • /me trollface 不能使用twisted有什么原因吗?

标签: python sockets gevent


【解决方案1】:

问题不在于套接字挂起,而是当套接字结束时您永远不会中断,从而创建了无限循环。这是修复它所需的代码:

with Timeout(5, False):
    while 1:
        data = s.recv(1024)
        if not data:
            break

        sock_buffer += data
        stop = time.time()

编辑: 一旦套接字完成连接,即使您调用#recv,它也不会产生greenlet 线程。因此,如果您希望超时能够触发,您需要使用 gevent.sleep() 手动让步:

with Timeout(5, False):
    while True:
        data = s.recv(1024)
        if data:
            sock_buffer += data
            stop = time.time()

        gevent.sleep()

来自 gevent 文档:“以 0 秒为单位调用 sleep 是表达合作收益的规范方式。”

【讨论】:

  • 如果我错了,请纠正我,但我认为这会破坏 Timeout 块的目的。收到数据后,我希望它等待并查看是否有更多数据进入,然后执行 5 秒钟。如果我在第一次收到后中断,那么我无法做到这一点。我在连接可能很慢并且不能一次全部接收到数据的环境中实现这个一般想法。最终,我试图找出每个套接字等待数据的等待时间。这是我计算等待时间的方法。想法?
  • 另外,请记住,我的方法适用于单个线程,但会挂起多个线程。
  • 啊,我明白你在问什么。我用答案更新了我的帖子。
  • 这让我更进一步 - 谢谢!然而,它不再挂起,现在一些线程有空缓冲区并且在没有收到任何数据的情况下完成。有什么想法吗?
  • 不确定 a.com、b.com 和 c.com 是否可以解决任何问题。这些是否会导致您的问题?
猜你喜欢
  • 2019-10-14
  • 1970-01-01
  • 2013-09-08
  • 2019-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多