2012-02-25 1 views
5

zmq.Pollerを使用して、stdinのデータ可用性をポーリングすることはできますか?そうでない場合、zeromqソケットのデータ可用性のために、ある時間(理想的に)ポーリングするのが最も効率的な待ち時間は何ですか。& stdinzeromq zmq.Poller&stdin

答えて

4

はい、zmqポーラー等STDIN、などのネイティブの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

+0

**警告**:これはWindowsでは動作しません(「アサーションに失敗しました:ソケットでないソケット操作」エラーが発生します)。これはおそらく、Windowsの 'select()'実装はソケット上でしか動作しないという事実に関連しています... –

1

あなたがWindows上で実行されることはありません確信している場合、あなたは、単にsys.stdinを登録することができますzmq.Pollerdescribed 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: 
     # ...