2012-02-25 23 views
5

Có thể sử dụng zmq.Poller cũng để thăm dò ý kiến ​​về tính khả dụng của dữ liệu trên stdin? Nếu không, điều gì sẽ là chờ đợi hiệu quả nhất để thăm dò ý kiến, tại một thời điểm nào đó (lý tưởng), để có sẵn dữ liệu trên ổ cắm zeromq & stdin?zeromq zmq.Poller & stdin

Trả lời

4

có, pollers zmq làm hỗ trợ FD bản xứ, bao gồm stdin, vv, do đó bạn chỉ cần kiểm tra 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: tuyệt vời. Cảm ơn! – jldupont

+0

** Cảnh báo **: điều này không hoạt động trên Windows (Tôi nhận được lỗi "Xác nhận không thành công: Ổ cắm hoạt động trên không có ổ cắm"). Điều này có thể liên quan đến thực tế là thực thi 'select()' của Windows chỉ hoạt động trên các socket ... –

1

Nếu bạn chắc chắn sẽ không bao giờ chạy trên Windows, bạn có thể chỉ cần đăng ký sys.stdin với số zmq.Poller (như described by minrk, above).

Tuy nhiên, select() implementation in Winsock chỉ hỗ trợ ổ cắm và không thể được sử dụng để thăm dò ý kiến ​​mô tả tệp "thông thường" như đầu vào chuẩn. Do đó, khi chạy trên Windows, bạn cần kết nối đầu vào tiêu chuẩn với ổ cắm 0MQ trên giao thức inproc.

thực hiện đề nghị sử dụng một ổ cắm cặp độc quyền:

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