1

特定のソケットからすべてのデータを受信するのにかかる時間を計算しようとしているので、「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()
4

1 に答える 1

3

問題は、ソケットがハングすることではありませんが、ソケットが終了しても壊れず、無限ループが作成されることです。これを修正するために必要なコードは次のとおりです。

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

        sock_buffer += data
        stop = time.time()

編集: ソケットが接続を完了すると、 を呼び出していても greenlet スレッドは生成されません#recv。したがって、タイムアウトを発生させたい場合は、次のように手動で生成する必要がありますgevent.sleep()

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

        gevent.sleep()

gevent のドキュメントから: 「秒数 0 でスリープを呼び出すことは、協力的な利回りを表現する標準的な方法です。」

于 2012-06-12T15:04:31.800 に答える