ZeroMQ does I/O in a background thread. When you create a new context, it starts with one I/O thread. To raise the number of I/O threads, use the zmq_ctx_set()
call before creating any sockets:
int io_threads = 4;
void *context = zmq_ctx_new();
zmq_ctx_set(context, ZMQ_IO_THREADS, io_threads);
assert(zmq_ctx_get(context, ZMQ_IO_THREADS) == io_threads);
Technically, the context is the container for all sockets in a single process, the acts as the transport for inproc sockets, which are the fastest way to connect threads in one process. If at runtime a process has two contexts, these are like seperate ZeroMQ instances.
It uses lock-free techniques for talking between nodes, so there are never locks, waits, semaphores, or deadlocks.
Core Msg Patten
Request-reply
REP-RESP socket pair. Client sends msg to the server, which replies with another msg. which connects a set of clients to a set of services. This is a remote procedure call and task distribution pattern.
As above of all: Ask and Ye Shall Receive.
Pub-sub
Getting the Message Out. Server pushes updates to a set of clients. which connects a set of publishers to a set of subscribers. This is a data distribution pattern.
PUB-SUB socket pair is asynchronous. The client does
zmq_recv()
, in a loop (or once if that’s all it needs). Trying to send a message to a SUB socket will cause an error. Similarly, the server does zmq_send()
as often as it needs to, but must not do zmq_recv()
on a PUB socket.
There is one more important thing to know about PUB-SUB sockets: you do not know precisely when a subscriber starts to get messages. 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. This is because as the subscriber connects to the publisher (something that takes a small but non-zero time), the publisher may already be sending messages out.
So, we need with REP-REQ pair to sync the information whether the publisher can push the data.
A more robust model could be:
- Publisher opens PUB socket and starts sending “Hello” messages (not data).
- Subscribers connect SUB socket and when they receive a Hello message they tell the publisher via a REQ/REP socket pair.
- When the publisher has had all the necessary confirmations, it starts to send real data.
Some points about the publish-subscribe (pub-sub) pattern:
- A subscriber can connect to more than one publisher, using one connect call each time. Data will then arrive and be interleaved (“fair-queued”) so that no single publisher drowns out the others.
- If a publisher has no connected subscribers, then it will simply drop all messages.
- If you’re using TCP and a subscriber is slow, messages will queue up on the publisher. We’ll look at how to protect publishers against this using the “high-water mark” later.
- From ZeroMQ v3.x, filtering happens at the publisher side when using a connected protocol (tcp:@<>@ or ipc:@<>@). Using the epgm:@<//>@ protocol, filtering happens at the subscriber side. In ZeroMQ v2.x, all filtering happened at the subscriber side.
Pipeline
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.
Exclusive pair
which connects two sockets exclusively. This is a pattern for connecting two threads in a process, not to be confused with “normal” pairs of sockets.
Socket type
unicast transports
- zmq_inproc
- zmq_ipc
- zmq_tcp
multicase transports
- zmq_pgm
- zmq_epgm