4

gevent.StreamServerテスト目的で使用する単純な tcp サーバーを作成しました。raw_input()一部のクライアントに応答を送信するには、できればスレッドを使用せずに、 を介して入力を処理する非ブロッキングの方法が必要です。

グーグルで調べた後、私はこの質問に出くわしました: eventlet.monkey_patch() を使用するときにブロックしない raw_input を作成する方法と、別のスレッドで実行された場合でもすべてをブロックする理由は?

私は次のように書いていますが、それは私が望んでいることを正確に実行しますが、より良いアプローチがあると思います。誰かが私を正しい方向に向けることができますか? また、try/except が KeyboardInterrupt をキャッチしない理由を教えていただければ幸いです。

import select
from gevent.monkey import patch_all
from gevent.server import StreamServer

patch_all(os=True, select=True)

def raw_input(message):
    """ Non-blocking input from stdin. """
    sys.stdout.write(message)

    select.select([sys.stdin], [], [])
    return sys.stdin.readline()

def main():
    """ Run the server, listen for commands """

    server = StreamServer(("0.0.0.0", 6000), handle)
    print "Starting server"
    gevent.signal(signal.SIGTERM, server.close)
    gevent.signal(signal.SIGQUIT, server.close)
    gevent.signal(signal.SIGINT, server.close)

    server.start()
    while True:
        try:
            a = raw_input("")
            if a:
                print "Received %s" % a
            gevent.sleep(0)
        except KeyboardInterrupt:
            print "Received a shutdown signal, going down ..."
            server.stop()
            sys.exit(0)

if __name__ == "__main__":
    main()

編集: コードの一部を書き直しましたが、main() 関数の愚かさを理解しました。誰かがこの質問につまずいて、その方法についてより良いアイデアを持っている場合に備えて、編集として投稿します。

from gevent.signal import signal

def get_console_input():
    """ Non-blocking console input to the server """

    select.select([sys.stdin], [], [])
    # There's quite a bit of code here but it is input handling so 
    # for shortness's sake   I've snipped everything and return the line read.
    return sys.stdin.readline()

def exit(server):
    """ Quit the server gracefully """

    print "Received shutdown signal, going down. """
    server.close()
    sys.exit(0)

def main():
    """ The main function. Create and run the server, listen for commands and
   append any command to the server so it can send them on to the clients """

    # Myserver is a class which inherits from gevent.server.StreamServer.
    # Myserver could just as well be replaced by gevent.server.StreamServer.

    server = MyServer(("0.0.0.0", PORT))
    print "Starting server"

    # Add some signal handlers to quit the server gracefully.
    gevent.signal(signal.SIGTERM, exit, server)
    gevent.signal(signal.SIGQUIT, exit, server)
    gevent.signal(signal.SIGINT, exit, server)

    # Server started in async mode
    server.start()

    while True:
        get_console_input()
        gevent.sleep(0)

if __name__ == "__main__":
    main()
4

1 に答える 1

5

これを行うために私が見つけた最も簡単な方法は、読み取り可能になるgevent.socket.wait_readまで待機することです。sys.stdin

wait_read(sys.stdin.fileno())
return sys.stdin.readline()

また、ファイル記述子の周りに小さなラッパーを作成して、ノンブロッキング.read().write()メソッドを提供しました: https://gist.github.com/2915875

于 2012-06-12T07:27:23.670 に答える