Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 套接字线程挂起在超时块中_Python_Sockets_Gevent - Fatal编程技术网

Python 套接字线程挂起在超时块中

Python 套接字线程挂起在超时块中,python,sockets,gevent,Python,Sockets,Gevent,我试图计算从给定套接字接收所有数据所需的时间,因此我使用“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):

我试图计算从给定套接字接收所有数据所需的时间,因此我使用“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()

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

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

        sock_buffer += data
        stop = time.time()
编辑: 一旦套接字完成连接,即使您正在调用
#recv
,它也不会产生greenlet线程。因此,如果您希望超时能够触发,则需要使用
gevent.sleep()


gevent文档中写道:“以秒为0调用sleep是表示合作收益的标准方式。”

/me trollface有什么原因不能使用twisted吗?如果我错了,请纠正我,但我认为这会破坏超时块的用途。一旦收到数据,我希望它等待,看看是否有更多的数据进来,并这样做5秒钟。如果我在第一次接收后就中断了,那么我就无法完成这项任务。我将在连接可能很慢且无法同时接收所有数据的环境中实现这一总体想法。最后,我试图计算每个套接字等待数据的等待时间。这是我计算等待时间的方法。想法?另外,请记住,我的方法将使用单个线程,但会挂起多个线程。啊,我明白你的要求。我用答案更新了我的帖子。这让我更进一步-谢谢!它不再挂起,但是,现在有几个线程有空的缓冲区,并且在没有收到任何数据的情况下完成。有什么想法吗?不确定a.com、b.com和c.com能解决什么问题。这些可能是你的问题吗?
with Timeout(5, False):
    while True:
        data = s.recv(1024)
        if data:
            sock_buffer += data
            stop = time.time()

        gevent.sleep()