zeromq zmq.Poller&标准输入

时间:2012-02-25 21:29:26

标签: python asynchronous zeromq epoll

是否可以使用zmq.Poller来轮询 stdin 上的数据可用性?如果没有,那么在某个时间(理想情况下),zeromq套接字上的数据可用性最有效的轮询是什么? 标准输入

2 个答案:

答案 0 :(得分:4)

是的,zmq pollers确实支持原生FD,包括stdin等,所以你只需要检查sys.stdin.fileno()

poller = zmq.Poller()
poller.register(sys.stdin, zmq.POLLIN)
poller.register(mysocket, zmq.POLLIN)
evts = dict(poller.poll(1000))
stdin_ready = evts.get(sys.stdin.fileno(), False)
socket_ready = evts.get(mysocket, False)

答案 1 :(得分:1)

如果您确定永远不会在Windows上运行,只需使用sys.stdindescribed by minrk, above)注册zmq.Poller

但是,select() implementation in Winsock仅支持套接字,不能用于轮询标准输入等“常规”文件描述符。因此,在Windows上运行时,需要在inproc传输中使用0MQ套接字桥接标准输入。

使用独占对套接字的建议实现:

def forward_lines(stream, socket):
    """Read lines from `stream` and send them over `socket`."""
    try:
        line = stream.readline()
        while line:
            socket.send(line[:-1])
            line = stream.readline()
        socket.send('')  # send "eof message".
    finally:
        # NOTE: `zmq.Context.term()` in the main thread will block until this
        #       socket is closed, so we can't run this function in daemon
        #       thread hoping that it will just close itself.
        socket.close()


def forward_standard_input(context):
    """Start a thread that will bridge the standard input to a 0MQ socket and
    return an exclusive pair socket from which you can read lines retrieved
    from the standard input.  You will receive a final empty line when the EOF
    character is input to the keyboard."""
    reader = context.socket(zmq.PAIR)
    reader.connect('inproc://standard-input')
    writer = context.socket(zmq.PAIR)
    writer.bind('inproc://standard-input')
    thread = threading.Thread(target=forward_lines,
                              args=(sys.stdin, writer))
    thread.start()
    return reader


if __name__ == '__main__':
    context = zmq.Context()
    reader = forward_standard_input(context)
    poller = zmq.Poller()
    poller.register(reader, zmq.POLLIN)
    poller.register(...)

    events = dict(poller.poll())
    if events.get(reader, 0) & zmq.POLLIN:
        line = reader.recv()
        # process line.
    if events.get(..., 0) & zmq.POLLIN:
        # ...