[zeromq-dev] "Wakeup call" to a thread blocked inside zmq_poll()?

MinRK benjaminrk at gmail.com
Mon Aug 13 20:49:37 CEST 2012


On Mon, Aug 13, 2012 at 11:05 AM, Arthur O'Dwyer <arthur at push.am> wrote:

> Hi all,
>
> I'm trying to use ZMQ in what I guess (surprisingly to me) is an
> unconventional way. The salient points of our protocol are:
>
> - The connection has only two ends: exactly one client and exactly one
> server.
>
> - In fact, the labels "client" and "server" are mostly unnecessary;
> requests can originate on either side. Sometimes the client asks the
> server something, and sometimes the server asks the client something.
>
> - Answers to questions don't come right away (requests and replies are
> not nicely nested). If the client has two things to ask the server, it
> can do both requests at once, and the server can spawn two worker
> threads to compute the answers in parallel.
>
> I believe the architecture we need is a work queue on each side: when
> a client thread asks a question, it puts a request packet P_a and a
> timeout value T_a into the "outbox" and then waits on a condition
> variable associated with that transaction-ID. There's a master ZMQ
> thread with three responsibilies:
>
>     - Whenever the outbox is non-empty, pull a message from it and
> send it over the wire.
>     - Whenever a request comes in over the wire, spawn a new worker
> thread to handle that request.
>     - Whenever a reply comes in over the wire, match its
> transaction-ID to our list of waiting workers and notify the worker
> who's waiting for this particular reply.
>     - T_a seconds after the request P_a goes out over the wire, if the
> reply hasn't come yet, notify the waiting worker that the reply has
> timed out.
>
> Also, we'd like to have a "heartbeat" in both directions. But I
> believe that can easily be handled as a special kind of worker thread
> on each side, whose only job is to send a request every N seconds and
> complain if the reply times out.
>
> This feels like a really simple and common architecture, and I also
> believe it would work out of the box if ZMQ supported calling
> zmq_poll() from multiple threads (because then we wouldn't even need
> the master thread; all of this queuing ickiness would happen inside
> ZMQ itself). But for the life of me I can't figure out how to get ZMQ
> to wait on "something is incoming over the wire *or*
> some-other-event", without just polling every millisecond inside a
> loop.
>
> Suppose Thread A is waiting inside zmq_poll(); is there any way for
> Thread B to say "Hey! Wake up right now! I need to send a message!"?
>

You can do this by creating a waker socket just for this purpose, and
always including it in the poll set:

https://gist.github.com/3343165

-MinRK



>
> Thanks much,
> -Arthur
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20120813/6b1c7d3e/attachment.htm>


More information about the zeromq-dev mailing list