6

私は、geventが採用している概念に頭を悩ませようとしています。gevent コード リポジトリの例を次に示します。これは単純なエコー サーバーです。

from gevent.server import StreamServer

# this handler will be run for each incoming connection in a dedicated greenlet
def echo(socket, address):
    print ('New connection from %s:%s' % address)
    socket.sendall('Welcome to the echo server! Type quit to exit.\r\n')
    # using a makefile because we want to use readline()
    fileobj = socket.makefile()
    while True:
        line = fileobj.readline()
        if not line:
            print ("client disconnected")
            break
        if line.strip().lower() == 'quit':
            print ("client quit")
            break
        fileobj.write(line)
        fileobj.flush()
        print ("echoed %r" % line)


if __name__ == '__main__':
    # to make the server use SSL, pass certfile and keyfile arguments to the constructor
    server = StreamServer(('0.0.0.0', 6000), echo)
    # to start the server asynchronously, use its start() method;
    # we use blocking serve_forever() here because we have no other jobs
    print ('Starting echo server on port 6000')
    server.serve_forever()

それは非常に簡単に思えますが、私はうまくいきます。serve_forever()ただし、ブロック機能であるコメントにあるように。最後の行を変更するとserver.start()、プログラムは各行を1回実行した後に停止します。私は何か間違ったことをしていますが、ドキュメントはあまり役に立ちません。

gevent を使用してサーバーを実装するドキュメント セクションではstart()、次のコードを使用する場合、 using は新しい接続ごとに新しい greenlet を生成する必要があると述べています。

 def handle(socket, address):
     print 'new connection!'

 server = StreamServer(('127.0.0.1', 1234), handle) # creates a new server
 server.start() # start accepting new connections

そして、それが最初の接続をキャッチするために実際に生きたままになるように、The server_forever() method calls start() and then waits until interrupted or until the server is stopped.どのようにサーバーを実行することになっているのですか?start()

また:

  1. start()とはどう違いserve_forever()ますか?
  2. どのような状況で、どちらか一方を選択する必要がありますか?
  3. gevent.spawn()最初のメソッドを使用するときにとの呼び出しがgevent.joinall()必要ですが、StreamServer のドキュメントから除外されていることは明らかですか?
4

1 に答える 1

12
  1. start() は、サーバーをリッスン モードにする非同期関数です。ただし、プログラムの終了を妨げるものではありません。これはあなたの責任です。
  2. 単純なケースでは、serve_forever() を使用できます。start() は、複数のサーバーを起動する必要がある場合、またはサーバーの起動に加えて何かを行う必要がある場合に役立ちます。
  3. いいえ、gevent.spawn() と gevent.joinall() はサーバーとは関係ありません。

gevent 1.0では、アクティブな接続/グリーンレット/リスナー/ウォッチャーがなくなるまでブロックする gevent.wait() を使用するのが実際には最善です。

例を次に示します: https://github.com/gevent/gevent/blob/master/examples/portforwarder.py

于 2012-04-24T06:42:59.703 に答える