title: Abort zeromq recv() or poll() from another thread - instantly and without the need to wait for timeout
body: <p>I'm using ZeroMQ in Python and C++ in many configurations and I wonder which is the most elegant way to abort a <code>recv()</code> or <code>poll()</code> from another thread (e.g. in case of controlled program termination but also if you want to stop listening without the need to kill the socket).</p>
  
  <p>In contrast to <a href="https://stackoverflow.com/questions/7538988/zeromq-how-to-prevent-infinite-wait">this</a> question I don't just want to avoid infinitive wait but I want to return <strong>immediately</strong> from <code>recv()</code> or <code>poll()</code>.</p>
  
  <p>I know I can just provide a <code>timeout</code> and abort <code>recv()</code> like this:</p>
  
  <pre><code>poller = zmq.Poller()
  poller.register(socket, zmq.POLLIN)
  
  while _running:
      if poller.poll(timeout=100) == []:
          # maybe handle unwanted timout here..
          continue
  
      handle_message(socket.recv())
  </code></pre>
  
  <p>This will poll the socket endlessly until <code>_running</code> is set to <code>False</code> from another thread - after a maximum of 100 ms I'm done.</p>
  
  <p>But this is not nice - I have a busy loop and it's hard this way to handle <em>real</em> timeouts which might be result of unwanted behavior. Also I have to 
  wait for the timeout which is not critical in most cases but.. you know what I mean.</p>
  
  <p>Of course I can poll an extra socket for abortion:</p>
  
  <pre><code>abort_socket = context.socket(zmq.SUB)
  abort_socket.setsockopt(zmq.SUBSCRIBE, b"")
  abort_socket.connect(&lt;abort-publisher-endpoint&gt;)
  
  poller = zmq.Poller()
  poller.register(socket, zmq.POLLIN)
  poller.register(abort_socket, zmq.POLLIN)
  
  while _running:
      poll_result = poller.poll(timeout=1000)
      if socket in poll_result:
          handle_message(socket.recv())
      elif abort_socket in poll_result:
          break
      else:
          # handle real timeout here
          pass
  </code></pre>
  
  <p>But this approach also has disadvantages:</p>
  
  <ul>
  <li>it's a bit <strong>verbose</strong> - at the place where I trigger the abort I would have to create a publisher and use that to abort the receiver</li>
  <li>the <code>abort_socket</code> can only be used from <strong>one thread</strong>, so I would have to make this sure</li>
  </ul>
  
  <p><strong>So my question is</strong>: how is this done the nice way? </p>
  
  <p>Can I somehow just use something like Python's <code>threading.Event</code> or s.th. similar in other languages rather than the abort-socket which can be passed to the poller like this?:</p>
  
  <pre><code>def listener_thread_fn(event)
  
      poller = zmq.Poller()
      poller.register(socket, zmq.POLLIN)
      poller.register(event, zmq.POLLIN)
  
      while _running:
          poll_result = poller.poll(timeout=1000)
          if socket in poll_result:
              handle_message(socket.recv())
          elif event in poll_result:
              break
          else:
              # handle real timeout here
              pass
  </code></pre>
  
  <p>So you just had to create a <code>theading.Event()</code> in the first place, pass it to <code>listener_thread_fn</code> and call <code>event.set()</code> from any thread to abort.</p>