<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://aznot.com/index.php?action=history&amp;feed=atom&amp;title=ZeroMQ</id>
	<title>ZeroMQ - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://aznot.com/index.php?action=history&amp;feed=atom&amp;title=ZeroMQ"/>
	<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=ZeroMQ&amp;action=history"/>
	<updated>2026-05-09T01:22:58Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://aznot.com/index.php?title=ZeroMQ&amp;diff=947&amp;oldid=prev</id>
		<title>Kenneth: /* Installation */</title>
		<link rel="alternate" type="text/html" href="https://aznot.com/index.php?title=ZeroMQ&amp;diff=947&amp;oldid=prev"/>
		<updated>2014-09-13T14:32:38Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Installation&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== ZeroMQ ==&lt;br /&gt;
&lt;br /&gt;
ZeroMQ (0MQ ZMQ) is a minimal Message-oriented middleware (MOM)&lt;br /&gt;
&lt;br /&gt;
zeromq - Distributed Computing Made Simple - http://zeromq.org/&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
python-zmq - Python bindings for 0MQ library&lt;br /&gt;
&lt;br /&gt;
Ubuntu/Debian/Raspberry Pi:&lt;br /&gt;
 apt-get install python-zmq&lt;br /&gt;
&lt;br /&gt;
 apt-get install python-dev&lt;br /&gt;
 pip install pyzmq&lt;br /&gt;
&lt;br /&gt;
Redhat: [http://zeromq.org/distro:centos]&lt;br /&gt;
 # redhat 5&lt;br /&gt;
 wget http://download.opensuse.org/repositories/home:/fengshuo:/zeromq/CentOS_CentOS-5/home:fengshuo:zeromq.repo -O /etc/yum.repos.d/zeromq.repo&lt;br /&gt;
 # redhat 6&lt;br /&gt;
 wget http://download.opensuse.org/repositories/home:/fengshuo:/zeromq/CentOS_CentOS-6/home:fengshuo:zeromq.repo -O /etc/yum.repos.d/zeromq.repo &lt;br /&gt;
&lt;br /&gt;
 yum install zeromq&lt;br /&gt;
 yum install zeromq-devel  # needed for pyzmq&lt;br /&gt;
&lt;br /&gt;
 pip install pyzmq&lt;br /&gt;
&lt;br /&gt;
=== Manual Installation ===&lt;br /&gt;
&lt;br /&gt;
Note: I couldn&amp;#039;t get it to work.&lt;br /&gt;
&lt;br /&gt;
Dependencies: libtool, autoconf, automake, e2fsprogs&lt;br /&gt;
&lt;br /&gt;
Library install:&lt;br /&gt;
 mkdir -p ~/.src ; cd ~/.src&lt;br /&gt;
 wget http://download.zeromq.org/zeromq-4.0.3.tar.gz&lt;br /&gt;
 tar -zvxf zeromq-4.0.3.tar.gz&lt;br /&gt;
 cd zeromq-4.0.3&lt;br /&gt;
 ./configure&lt;br /&gt;
 make&lt;br /&gt;
 sudo make install&lt;br /&gt;
 sudo ldconfig&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
Python binding install: [http://zeromq.org/bindings:python]&lt;br /&gt;
 easy_install pyzmq&lt;br /&gt;
 # or&lt;br /&gt;
 pip install pyzmq&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
Alternate path&lt;br /&gt;
&lt;br /&gt;
 # ...&lt;br /&gt;
 tar -zvxf zeromq-4.0.3.tar.gz&lt;br /&gt;
 cd zeromq-4.0.3&lt;br /&gt;
 ./configure --prefix=/opt/zeromq&lt;br /&gt;
 make clean&lt;br /&gt;
 make&lt;br /&gt;
 sudo make install&lt;br /&gt;
 sudo /sbin/ldconfig -v -n /opt/zeromq/lib/  # creates generic links&lt;br /&gt;
&lt;br /&gt;
 PKG_CONFIG_PATH=/opt/zeromq/lib/pkgconfig/  sudo pip install --upgrade pyzmq&lt;br /&gt;
&lt;br /&gt;
== Python Guide ==&lt;br /&gt;
&lt;br /&gt;
ØMQ - The Guide - ØMQ - The Guide - http://zguide.zeromq.org/py:all&lt;br /&gt;
* PDF Version - http://zguide2.wdfiles.com/local--files/page:start/zguide-py.pdf&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
 git clone --depth=1 git://github.com/imatix/zguide.git&lt;br /&gt;
&lt;br /&gt;
== eBooks ==&lt;br /&gt;
&lt;br /&gt;
=== ZeroMQ by Pieter Hintjens ===&lt;br /&gt;
&lt;br /&gt;
ZeroMQ By Pieter Hintjens - O&amp;#039;Reilly Media - http://shop.oreilly.com/product/0636920026136.do&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Dive into ZeroMQ, the smart socket library that gives you fast, easy, message-based concurrency for your applications. With this quick-paced guide, you&amp;#039;ll learn hands-on how to use this scalable, lightweight, and highly flexible networking tool for exchanging messages among clusters, the cloud, and other multi-system environments.&lt;br /&gt;
&lt;br /&gt;
ZeroMQ maintainer Pieter Hintjens takes you on a tour of real-world applications, using extended examples in C to help you work with ZeroMQ&amp;#039;s API, sockets, and patterns. Learn how to use specific ZeroMQ programming techniques, build multithreaded applications, and create your own messaging architectures. You&amp;#039;ll discover how ZeroMQ works with several programming languages and most operating systems - with little or no cost.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
ZeroMQ - Free Download eBook - pdf http://filepi.com/i/qo5Uv2G&lt;br /&gt;
&lt;br /&gt;
=== ZeroMQ by Faruk Akgul ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ØMQ (also spelled ZeroMQ, 0MQ, or ZMQ) is a high-performance asynchronous messaging library aimed at use in scalable distributed or concurrent applications. It provides a message queue, but unlike message-oriented middleware, a ØMQ system can run without a dedicated message broker. The library is designed to have a familiar socket-style API.&lt;br /&gt;
&lt;br /&gt;
ZeroMQ teaches you to use ZeroMQ through examples in C programming language. You will learn how to use fundamental patterns of message / queuing with a step-by-step tutorial approach and how to apply them. Then, you&amp;#039;ll learn how to use high level APIs and to work with multiple sockets and multithreaded programs through many examples.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Download:&lt;br /&gt;
* ZeroMQ - Free Download eBook - pdf - http://it-ebooks.info/book/2780/&lt;br /&gt;
* ZeroMQ pdf | EBook Free Download - http://ebooknew.net/2013/09/zeromq-pdf.html&lt;br /&gt;
* http://dl.e-book-free.com/2013/07/zeromq.pdf&lt;br /&gt;
&lt;br /&gt;
== Patterns ==&lt;br /&gt;
&lt;br /&gt;
The built-in core ØMQ patterns are:&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Request-reply&amp;#039;&amp;#039;&amp;#039;, which connects a set of clients to a set of services. This is a remote procedure call and task distribution pattern.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Pub-sub&amp;#039;&amp;#039;&amp;#039;, which connects a set of publishers to a set of subscribers. This is a data distribution pattern.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Pipeline&amp;#039;&amp;#039;&amp;#039;, which connects nodes in a fan-out/fan-in pattern that can have multiple steps and loops. This is a parallel task distribution and collection pattern.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Exclusive pair&amp;#039;&amp;#039;&amp;#039;, which connects two sockets exclusively. This is a pattern for connecting two threads in a process, not to be confused with &amp;quot;normal&amp;quot; pairs of sockets.&lt;br /&gt;
&lt;br /&gt;
=== Request-Reply ===&lt;br /&gt;
&lt;br /&gt;
REQuest REPly&lt;br /&gt;
&lt;br /&gt;
https://github.com/imatix/zguide/raw/master/images/fig2.png&lt;br /&gt;
&lt;br /&gt;
This is the request-reply pattern, probably the simplest way to use ØMQ. It maps to RPC and the classic client/server model.&lt;br /&gt;
&lt;br /&gt;
Warning: Must be synchronized.  Both send and receive block.  You cannot send if there is something waiting on the receive queue (or vice a versa)!  Each request must be met with a reply.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;The REQ-REP socket pair is in lockstep. The client issues zmq_send() and then zmq_recv(), in a loop (or once if that&amp;#039;s all it needs). Doing any other sequence (e.g., sending two messages in a row) will result in a return code of -1 from the send or recv call. Similarly, the service issues zmq_recv() and then zmq_send() in that order, as often as it needs to.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
zmq_hello_server.py :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import zmq&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
context = zmq.Context()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;starting server...&amp;quot;&lt;br /&gt;
socket = context.socket(zmq.REP)&lt;br /&gt;
socket.bind(&amp;quot;tcp://*:5555&amp;quot;)&lt;br /&gt;
print &amp;quot;server started.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    print &amp;quot;waiting for data...&amp;quot;&lt;br /&gt;
    message = socket.recv()&lt;br /&gt;
    print &amp;quot;recv:&amp;quot;, message&lt;br /&gt;
&lt;br /&gt;
    print &amp;quot;send:&amp;quot;, message&lt;br /&gt;
    socket.send(message)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
zmq_hello_client.py :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import zmq&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
context = zmq.Context()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;connecting to server...&amp;quot;&lt;br /&gt;
socket = context.socket(zmq.REQ)&lt;br /&gt;
socket.connect(&amp;quot;tcp://localhost:5555&amp;quot;)&lt;br /&gt;
print &amp;quot;connected to server.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
i = 1&lt;br /&gt;
while True:&lt;br /&gt;
    i = i + 1&lt;br /&gt;
    print &amp;quot;send:&amp;quot;, i&lt;br /&gt;
    socket.send(str(i))&lt;br /&gt;
&lt;br /&gt;
    message = socket.recv()&lt;br /&gt;
    print &amp;quot;message:&amp;quot;, message&lt;br /&gt;
&lt;br /&gt;
    time.sleep(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Publish-Subscribe ===&lt;br /&gt;
&lt;br /&gt;
One way to many communication.&lt;br /&gt;
&lt;br /&gt;
https://github.com/imatix/zguide/raw/master/images/fig4.png&lt;br /&gt;
&lt;br /&gt;
Error if you try to send to a SUB socket, or receive on a PUB socket.&lt;br /&gt;
&lt;br /&gt;
The PUB-SUB socket pair is asynchronous.  Messages will queue up if you don&amp;#039;t receive them fast enough.&lt;br /&gt;
&lt;br /&gt;
Subscribe - &amp;quot;Note that when you use a SUB socket you must set a subscription using zmq_setsockopt() and SUBSCRIBE, as in this code. If you don&amp;#039;t set any subscription, you won&amp;#039;t get any messages. It&amp;#039;s a common mistake for beginners. The subscriber can set many subscriptions, which are added together. That is, if an update matches ANY subscription, the subscriber receives it. The subscriber can also cancel specific subscriptions. A subscription is often, but not necessarily a printable string.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Subscribe Filter - &amp;quot;The ZMQ_SUBSCRIBE option shall establish a new message filter on a ZMQ_SUB socket. Newly created ZMQ_SUB sockets shall filter out all incoming messages, therefore you should call this option to establish an initial message filter. An empty option_value of length zero shall subscribe to all incoming messages. A non-empty option_value shall subscribe to all messages beginning with the specified prefix. Multiple filters may be attached to a single ZMQ_SUB socket, in which case a message shall be accepted if it matches at least one filter.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Binding - &amp;quot;In theory with ØMQ sockets, it does not matter which end connects and which end binds. However, in practice there are undocumented differences that I&amp;#039;ll come to later. For now, bind the PUB and connect the SUB, unless your network design makes that impossible.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Slow joiner - &amp;quot;Even if you start a subscriber, wait a while, and then start the publisher, the subscriber will always miss the first messages that the publisher sends.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Synchronize - &amp;quot;In Chapter 2 - Sockets and Patterns we&amp;#039;ll explain how to synchronize a publisher and subscribers so that you don&amp;#039;t start to publish data until the subscribers really are connected and ready. The alternative to synchronization is to simply assume that the published data stream is infinite and has no start and no end. One also assumes that the subscriber doesn&amp;#039;t care what transpired before it started up.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
zmq_pub_server.py&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Weather update server&lt;br /&gt;
# Binds PUB socket to tcp://*:5556&lt;br /&gt;
# Publishes random weather updates&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
import zmq&lt;br /&gt;
from random import randrange&lt;br /&gt;
&lt;br /&gt;
context = zmq.Context()&lt;br /&gt;
socket = context.socket(zmq.PUB)&lt;br /&gt;
socket.bind(&amp;quot;tcp://*:5556&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
    zipcode = randrange(1, 100000)&lt;br /&gt;
    temperature = randrange(1, 215) - 80&lt;br /&gt;
    relhumidity = randrange(1, 50) + 10&lt;br /&gt;
&lt;br /&gt;
    socket.send(&amp;quot;%d %d %d&amp;quot; % (zipcode, temperature, relhumidity))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
zmq_pub_client.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Weather update client&lt;br /&gt;
# Connects SUB socket to tcp://localhost:5556&lt;br /&gt;
# Collects weather updates and finds avg temp in zipcode&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import zmq&lt;br /&gt;
&lt;br /&gt;
# Socket to talk to server&lt;br /&gt;
context = zmq.Context()&lt;br /&gt;
socket = context.socket(zmq.SUB)&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Collecting updates from weather server…&amp;quot;&lt;br /&gt;
socket.connect(&amp;quot;tcp://localhost:5556&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Subscribe to zipcode, default is NYC, 10001&lt;br /&gt;
zip_filter = sys.argv[1] if len(sys.argv) &amp;gt; 1 else &amp;quot;10001&amp;quot;&lt;br /&gt;
socket.setsockopt(zmq.SUBSCRIBE, zip_filter)&lt;br /&gt;
&lt;br /&gt;
# Process 5 updates&lt;br /&gt;
total_temp = 0&lt;br /&gt;
for update_nbr in range(5):&lt;br /&gt;
    string = socket.recv()&lt;br /&gt;
    zipcode, temperature, relhumidity = string.split()&lt;br /&gt;
    total_temp += int(temperature)&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Average temperature for zipcode &amp;#039;%s&amp;#039; was %dF&amp;quot; % (&lt;br /&gt;
        zip_filter, total_temp / update_nbr)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
This shows a filter that collects data from two different remote publishers and sends it to local subscribers: [http://zeromq.org/intro:read-the-manual]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import zmq&lt;br /&gt;
import time&lt;br /&gt;
context = zmq.Context()&lt;br /&gt;
 &lt;br /&gt;
subscriber = context.socket (zmq.SUB)&lt;br /&gt;
subscriber.connect (&amp;quot;tcp://192.168.55.112:5556&amp;quot;)&lt;br /&gt;
subscriber.connect (&amp;quot;tcp://192.168.55.201:7721&amp;quot;)&lt;br /&gt;
subscriber.setsockopt (zmq.SUBSCRIBE, &amp;quot;NASDAQ&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
publisher = context.socket (zmq.PUB)&lt;br /&gt;
publisher.bind (&amp;quot;ipc://nasdaq-feed&amp;quot;)&lt;br /&gt;
 &lt;br /&gt;
while True:&lt;br /&gt;
    message = subscriber.recv()&lt;br /&gt;
    publisher.send (message)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
 # Subscribe on everything&lt;br /&gt;
 frontend.setsockopt(zmq.SUBSCRIBE, &amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
=== Parallel Pipeline ===&lt;br /&gt;
&lt;br /&gt;
Dive and Conquer - task distribution&lt;br /&gt;
&lt;br /&gt;
PUSH (send) and PULL (recv) - both blocking on consumer/producer&lt;br /&gt;
&lt;br /&gt;
Tasks will be divided out fairly among workers.&lt;br /&gt;
&lt;br /&gt;
https://github.com/imatix/zguide/raw/master/images/fig5.png&lt;br /&gt;
&lt;br /&gt;
Our supercomputing application is a fairly typical parallel processing model. We have:&lt;br /&gt;
* A ventilator that produces tasks that can be done in parallel&lt;br /&gt;
* A set of workers that process tasks&lt;br /&gt;
* A sink that collects results back from the worker processes&lt;br /&gt;
&lt;br /&gt;
Server:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import zmq&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
context = zmq.Context()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;starting server...&amp;quot;&lt;br /&gt;
socket = context.socket(zmq.PUB)&lt;br /&gt;
socket.bind(&amp;quot;tcp://*:5555&amp;quot;)&lt;br /&gt;
print &amp;quot;server started.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
i = 1&lt;br /&gt;
while True:&lt;br /&gt;
    try:&lt;br /&gt;
        print i&lt;br /&gt;
        socket.send(str(i))&lt;br /&gt;
        i = i + 1&lt;br /&gt;
    except zmq.error.ZMQError:&lt;br /&gt;
        pass&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Client:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import zmq&lt;br /&gt;
import time&lt;br /&gt;
&lt;br /&gt;
context = zmq.Context()&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;connecting to server...&amp;quot;&lt;br /&gt;
socket = context.socket(zmq.SUB)&lt;br /&gt;
socket.connect(&amp;quot;tcp://localhost:5555&amp;quot;)&lt;br /&gt;
socket.setsockopt(zmq.SUBSCRIBE, &amp;#039;&amp;#039;)&lt;br /&gt;
print &amp;quot;connected to server.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
last = 0&lt;br /&gt;
while True:&lt;br /&gt;
    try:&lt;br /&gt;
        message = socket.recv()&lt;br /&gt;
        print &amp;quot;message:&amp;quot;, message&lt;br /&gt;
        current = int(message)&lt;br /&gt;
        if current != last + 1:&lt;br /&gt;
            print &amp;quot;err count&amp;quot;, current, last&lt;br /&gt;
        last = current&lt;br /&gt;
    except zmq.error.ZMQError as err:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
    time.sleep(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== code ==&lt;br /&gt;
&lt;br /&gt;
=== version ===&lt;br /&gt;
&lt;br /&gt;
 $ python -c &amp;#039;import zmq ; print zmq.zmq_version()&amp;#039;&lt;br /&gt;
 4.0.4&lt;br /&gt;
&lt;br /&gt;
=== non blocking receive ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
while True:&lt;br /&gt;
  try:&lt;br /&gt;
    rc = receiver.recv(zmq.DONTWAIT)&lt;br /&gt;
  except zmq.ZMQError:&lt;br /&gt;
    break&lt;br /&gt;
&lt;br /&gt;
  # do work&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  # No activity, so sleep for 1 msec&lt;br /&gt;
  time.sleep(0.001)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== polling ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Initialize poll set&lt;br /&gt;
poller = zmq.Poller()&lt;br /&gt;
poller.register(receiver, zmq.POLLIN)&lt;br /&gt;
poller.register(subscriber, zmq.POLLIN)&lt;br /&gt;
&lt;br /&gt;
while True:&lt;br /&gt;
  socks = dict(poller.poll())&lt;br /&gt;
&lt;br /&gt;
  #if receiver in socks and socks[receiver] == zmq.POLLIN:&lt;br /&gt;
  if socks.get(receiver) == zmq.POLLIN:&lt;br /&gt;
    message = receiver.recv()&lt;br /&gt;
&lt;br /&gt;
  # do work&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Poll Timeout:&lt;br /&gt;
 poller.poll(5000)  # 5 second timeout&lt;br /&gt;
&lt;br /&gt;
Simpler check, if only one poller:&lt;br /&gt;
 evts = poller.poll()&lt;br /&gt;
 if evts:&lt;br /&gt;
    message = receiver.recv()&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
Nicholas Piël » ZeroMQ an introduction - http://nichol.as/zeromq-an-introduction&lt;br /&gt;
: &amp;quot;ZeroMQ is a messaging library, which allows you to design a complex communication system without much effort. It has been wrestling with how to effectively describe itself in the recent years. In the beginning it was introduced as ‘messaging middleware’ later they moved to ‘TCP on steroids’ and right now it is a ‘new layer on the networking stack’.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Message Queue Comparisons ==&lt;br /&gt;
&lt;br /&gt;
Message Queue Evaluation Notes - Second Life Wiki - http://wiki.secondlife.com/wiki/Message_Queue_Evaluation_Notes&lt;br /&gt;
&lt;br /&gt;
== Failure Philosophy ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;ØMQ&amp;#039;s error handling philosophy is a mix of fail-fast and resilience. Processes, we believe, should be as vulnerable as possible to internal errors, and as robust as possible against external attacks and errors. To give an analogy, a living cell will self-destruct if it detects a single internal error, yet it will resist attack from the outside by all means possible.&lt;br /&gt;
&lt;br /&gt;
Assertions, which pepper the ØMQ code, are absolutely vital to robust code; they just have to be on the right side of the cellular wall. And there should be such a wall. If it is unclear whether a fault is internal or external, that is a design flaw to be fixed.&amp;quot; [http://zguide.zeromq.org/py:all]&lt;br /&gt;
&lt;br /&gt;
== Sender Receiver with Kill ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Adds pub-sub flow to receive and respond to kill signal&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import time&lt;br /&gt;
import zmq&lt;br /&gt;
&lt;br /&gt;
context = zmq.Context()&lt;br /&gt;
&lt;br /&gt;
# Socket to receive messages on&lt;br /&gt;
receiver = context.socket(zmq.PULL)&lt;br /&gt;
receiver.connect(&amp;quot;tcp://localhost:5557&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Socket to send messages to&lt;br /&gt;
sender = context.socket(zmq.PUSH)&lt;br /&gt;
sender.connect(&amp;quot;tcp://localhost:5558&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Socket for control input&lt;br /&gt;
controller = context.socket(zmq.SUB)&lt;br /&gt;
controller.connect(&amp;quot;tcp://localhost:5559&amp;quot;)&lt;br /&gt;
controller.setsockopt(zmq.SUBSCRIBE, &amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Process messages from receiver and controller&lt;br /&gt;
poller = zmq.Poller()&lt;br /&gt;
poller.register(receiver, zmq.POLLIN)&lt;br /&gt;
poller.register(controller, zmq.POLLIN)&lt;br /&gt;
# Process messages from both sockets&lt;br /&gt;
while True:&lt;br /&gt;
    socks = dict(poller.poll())&lt;br /&gt;
&lt;br /&gt;
    if socks.get(receiver) == zmq.POLLIN:&lt;br /&gt;
        message = receiver.recv()&lt;br /&gt;
&lt;br /&gt;
        # Process task&lt;br /&gt;
        workload = int(message) # Workload in msecs&lt;br /&gt;
&lt;br /&gt;
        # Do the work&lt;br /&gt;
        time.sleep(workload / 1000.0)&lt;br /&gt;
&lt;br /&gt;
        # Send results to sink&lt;br /&gt;
        sender.send(message)&lt;br /&gt;
&lt;br /&gt;
        # Simple progress indicator for the viewer&lt;br /&gt;
        sys.stdout.write(&amp;quot;.&amp;quot;)&lt;br /&gt;
        sys.stdout.flush()&lt;br /&gt;
&lt;br /&gt;
    # Any waiting controller command acts as &amp;#039;KILL&amp;#039;&lt;br /&gt;
    if socks.get(controller) == zmq.POLLIN:&lt;br /&gt;
        break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handle Ctrl-C ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
# Shows how to handle Ctrl-C&lt;br /&gt;
#&lt;br /&gt;
import zmq&lt;br /&gt;
import signal&lt;br /&gt;
&lt;br /&gt;
interrupted = False&lt;br /&gt;
&lt;br /&gt;
def signal_handler(signum, frame):&lt;br /&gt;
global interrupted&lt;br /&gt;
interrupted = True&lt;br /&gt;
&lt;br /&gt;
context = zmq.Context()&lt;br /&gt;
socket = context.socket(zmq.REP)&lt;br /&gt;
socket.bind(&amp;quot;tcp://*:5558&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# SIGINT will normally raise a KeyboardInterrupt, just like any other Python call&lt;br /&gt;
try:&lt;br /&gt;
    socket.recv()&lt;br /&gt;
except KeyboardInterrupt:&lt;br /&gt;
    print &amp;quot;W: interrupt received, proceeding…&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# or you can use a custom handler&lt;br /&gt;
counter = 0&lt;br /&gt;
signal.signal(signal.SIGINT, signal_handler)&lt;br /&gt;
while True:&lt;br /&gt;
    try:&lt;br /&gt;
        message = socket.recv(zmq.DONTWAIT)&lt;br /&gt;
    except zmq.ZMQError:&lt;br /&gt;
        pass&lt;br /&gt;
    counter += 1&lt;br /&gt;
    if interrupted:&lt;br /&gt;
        print &amp;quot;W: interrupt received, killing server…&amp;quot;&lt;br /&gt;
        break&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If your code is blocking in a blocking call (sending a message, receiving a message, or polling), then when a signal arrives, the call will return with EINTR.&lt;br /&gt;
&lt;br /&gt;
== Multithreading with ØMQ ==&lt;br /&gt;
&lt;br /&gt;
Multithreading (MT) Programming&lt;br /&gt;
&lt;br /&gt;
If there&amp;#039;s one lesson we&amp;#039;ve learned from 30+ years of concurrent programming, it is: just don&amp;#039;t share state. It&amp;#039;s like two drunkards trying to share a beer. It doesn&amp;#039;t matter if they&amp;#039;re good buddies. Sooner or later, they&amp;#039;re going to get into a fight. And the more drunkards you add to the table, the more they fight each other over the beer. The tragic majority of MT applications look like drunken bar fights.&lt;br /&gt;
&lt;br /&gt;
You should follow some rules to write happy multithreaded code with ØMQ:&lt;br /&gt;
* Isolate data privately within its thread and never share data in multiple threads. The only exception to this are ØMQ contexts, which are threadsafe.&lt;br /&gt;
* Stay away from the classic concurrency mechanisms like as mutexes, critical sections, semaphores, etc. These are an anti-pattern in ØMQ applications.&lt;br /&gt;
* Create one ØMQ context at the start of your process, and pass that to all threads that you want to connect via inproc sockets.&lt;br /&gt;
* Use attached threads to create structure within your application, and connect these to their parent threads using PAIR sockets over inproc. The pattern is: bind parent socket, then create child thread which connects its socket.&lt;br /&gt;
* Use detached threads to simulate independent tasks, with their own contexts. Connect these over tcp. Later you can move these to stand-alone processes without changing the code significantly.&lt;br /&gt;
* All interaction between threads happens as ØMQ messages, which you can define more or less formally.&lt;br /&gt;
* Don&amp;#039;t share ØMQ sockets between threads. ØMQ sockets are not threadsafe. Technically it&amp;#039;s possible to migrate a socket from one thread to another but it demands skill. The only place where it&amp;#039;s remotely sane to share sockets between threads are in language bindings that need to do magic like garbage collection on sockets.&lt;br /&gt;
&lt;br /&gt;
=== Threading ===&lt;br /&gt;
&lt;br /&gt;
The MT version of the Hello World service basically collapses the broker and workers into a single process:&lt;br /&gt;
&lt;br /&gt;
https://github.com/imatix/zguide/raw/master/images/fig20.png&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Multithreaded Hello World server&lt;br /&gt;
&lt;br /&gt;
Author: Guillaume Aubert (gaubert) &amp;lt;guillaume(dot)aubert(at)gmail(dot)com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
import time&lt;br /&gt;
import threading&lt;br /&gt;
import zmq&lt;br /&gt;
&lt;br /&gt;
def worker_routine(worker_url, context):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; Worker routine &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Socket to talk to dispatcher&lt;br /&gt;
    socket = context.socket(zmq.REP)&lt;br /&gt;
&lt;br /&gt;
    socket.connect(worker_url)&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
&lt;br /&gt;
        string = socket.recv()&lt;br /&gt;
&lt;br /&gt;
        print(&amp;quot;Received request: [%s]\n&amp;quot; % (string))&lt;br /&gt;
&lt;br /&gt;
        # do some &amp;#039;work&amp;#039;&lt;br /&gt;
        time.sleep(1)&lt;br /&gt;
&lt;br /&gt;
        #send reply back to client&lt;br /&gt;
        socket.send(&amp;quot;World&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot; server routine &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    url_worker = &amp;quot;inproc://workers&amp;quot;&lt;br /&gt;
    url_client = &amp;quot;tcp://*:5555&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Prepare our context and sockets&lt;br /&gt;
    context = zmq.Context(1)&lt;br /&gt;
&lt;br /&gt;
    # Socket to talk to clients&lt;br /&gt;
    clients = context.socket(zmq.ROUTER)&lt;br /&gt;
    clients.bind(url_client)&lt;br /&gt;
&lt;br /&gt;
    # Socket to talk to workers&lt;br /&gt;
    workers = context.socket(zmq.DEALER)&lt;br /&gt;
    workers.bind(url_worker)&lt;br /&gt;
&lt;br /&gt;
    # Launch pool of worker threads&lt;br /&gt;
    for i in range(5):&lt;br /&gt;
        thread = threading.Thread(target=worker_routine, args=(url_worker, context, ))&lt;br /&gt;
        thread.start()&lt;br /&gt;
&lt;br /&gt;
    zmq.device(zmq.QUEUE, clients, workers)&lt;br /&gt;
&lt;br /&gt;
    # We never get here but clean up anyhow&lt;br /&gt;
    clients.close()&lt;br /&gt;
    workers.close()&lt;br /&gt;
    context.term()&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== keywords ==&lt;br /&gt;
&lt;br /&gt;
ZeroMQ 0MQ ZMQ MOM Message-oriented middleware&lt;br /&gt;
&lt;br /&gt;
[[Category:Linux]]&lt;br /&gt;
[[Category:Python]]&lt;br /&gt;
[[Category:MOM]]&lt;/div&gt;</summary>
		<author><name>Kenneth</name></author>
	</entry>
</feed>