首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >gevent.StreamServer和非阻塞raw_input()?

gevent.StreamServer和非阻塞raw_input()?
EN

Stack Overflow用户
提问于 2012-05-15 21:09:15
回答 1查看 3.1K关注 0票数 4

出于测试目的,我已经使用gevent.StreamServer编写了一个简单的tcp服务器。为了让我向一些客户端发送响应,我需要一种非阻塞的方式来处理通过raw_input()的输入,最好不要使用线程。

在谷歌了一下之后,我偶然发现了这个问题:How to make non-blocking raw_input when using eventlet.monkey_patch() and why it block everything, even when executed on another thread?

我已经写了下面的代码,它做的正是我想要的,不过我假设有更好的方法。谁能给我指个方向?此外,我们也希望了解一下为什么try/except不能捕获KeyboardInterrupt。

代码语言:javascript
运行
复制
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()-function的愚蠢之处。我会将其作为编辑后发布,以防有人偶然发现这个问题,并对如何做有更好的想法。

代码语言:javascript
运行
复制
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()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-06-12 15:27:24

我找到的最简单的方法是使用gevent.socket.wait_read等待,直到可以读取sys.stdin

代码语言:javascript
运行
复制
wait_read(sys.stdin.fileno())
return sys.stdin.readline()

我还编写了一个围绕文件描述符的小包装器,为它们提供非阻塞的.read().write()方法:https://gist.github.com/2915875

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10601382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档