Если вы уверены, что никогда не будете работать в 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:
# ...