zeromq zmq.Poller & stdin - PullRequest
       12

zeromq zmq.Poller & stdin

5 голосов
/ 26 февраля 2012

Можно ли использовать zmq.Poller для опроса доступности данных на stdin ? Если нет, то какое было бы наиболее эффективное ожидание для опроса, в какое-то время (в идеале), доступности данных на сокетах zeromq & stdin ?

Ответы [ 2 ]

4 голосов
/ 26 февраля 2012

да, опросы zmq поддерживают собственные 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 голос
/ 28 декабря 2013

Если вы уверены, что никогда не будете работать в Windows, вы можете просто зарегистрировать sys.stdin с zmq.Poller (как , описанное minrk, выше ).

Однако реализация select() в Winsock поддерживает только сокеты и не может использоваться для опроса «обычных» файловых дескрипторов, таких как стандартный ввод. Поэтому при работе в Windows вам необходимо соединить стандартный ввод с сокетом 0MQ на транспорте inproc.

Предлагаемая реализация с использованием монопольного сокета пары:

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:
        # ...
...