2012-02-25 76 views
5

是否有可能使用zmq.Poller來輪詢數據可用性stdin?如果不是這樣,這將是最有效的等待輪詢,在一段時間內(理想情況下),對數據可用性上zeromq插座& 標準輸入zeromq zmq.Poller&stdin

回答

4

是,ZMQ輪詢做支持本地的FD,包括標準輸入,等等,所以你只需要檢查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) 
+0

1:奇妙。謝謝! – jldupont 2012-02-26 13:02:47

+0

**警告**:這在Windows上不起作用(我得到「斷言失敗:在非套接字上的套接字操作」錯誤)。這可能與Windows的select()實現僅適用於套接字有關。 – 2013-12-27 18:49:34

1

如果你確信你將永遠不會在Windows上運行,你可以簡單地註冊sys.stdinzmq.Poller(如described by minrk, above)。

然而,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: 
     # ...