2012-02-25 14 views
5

पर stdin पर डेटा उपलब्धता के लिए मतदान के लिए भी zmq.Poller का उपयोग करना संभव है? यदि नहीं, तो ज़ीरोम सॉकेट & stdin पर डेटा उपलब्धता के लिए, कुछ समय (आदर्श) पर मतदान के लिए सबसे प्रभावी प्रतीक्षा क्या होगी?zeromq zmq.Poller और stdin

उत्तर

4

हाँ, zmq pollers 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) 
+0

+1: अद्भुत। धन्यवाद! – jldupont

+0

** चेतावनी **: यह विंडोज पर काम नहीं करता है (मुझे "असफलता विफल: गैर सॉकेट पर सॉकेट ऑपरेशन" त्रुटि मिलती है)। यह शायद इस तथ्य से संबंधित है कि विंडोज़ 'चयन() 'कार्यान्वयन केवल सॉकेट पर काम करता है ... –

1

क्या आप वाकई विंडोज पर चलने कभी नहीं होगा रहे हैं, तो आप बस रजिस्टर कर सकते हैं sys.stdinzmq.Poller (described by minrk, above के रूप में) के साथ।

हालांकि, select() implementation in Winsock केवल सॉकेट का समर्थन करता है और मानक इनपुट जैसे "नियमित" फ़ाइल डिस्क्रिप्टरों को मतदान करने के लिए उपयोग नहीं किया जा सकता है। इसलिए, जब विंडोज़ पर चलते हैं, तो आपको इनप्रोक ट्रांसपोर्ट पर 0 एमक्यू सॉकेट के साथ मानक इनपुट को पुल करने की आवश्यकता होती है।

सुझाए गए एक विशेष जोड़ी सॉकेट का उपयोग कर कार्यान्वयन:

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