[zeromq-dev] Best practice

Martin Sustrik sustrik at fastmq.com
Thu Apr 9 19:41:05 CEST 2009


Hi Todd,

I cannot compile your code as it's just bits and pieces, however, I am
attaching a functional code (tested with 0MQ/0.6 on Linux). Have a look
at it.

Few comments:

1. You don't need to create the I/O thread. You are doing no I/O, just
passing messages within a process, so there's no need for it.

2. When sending a message you don't supply deallocation function. This
means 0MQ won't deallocate the buffer once it is not needed => memory leak.

Hop this helps!
Martin

Todd Gruben wrote:
> excellent reply, thanks for that.  I am still having a bit of a time.  
> Messages are going into the exchange, but I never see them on the 
> receiver side.  Here is the gist of my app
> 
> mainthread:
>    locator_t l(NULL);// the process locator
>     dispatcher_t dispatch (feedcount + 2); //feeds + main+receiver
> 
> producer threads:
>                     i_thread *pt = io_thread_t::create (&_dispatch);
>                     api_thread_t *api = api_thread_t::create 
> (&_dispatch, &_locator);
>                     int eid = api->create_exchange ("E",scope_local);
>                     api->bind ("E", "Q",pt,pt);
> while(readdata){
>                         message_t message((void*)data,data._rec_size,NULL);
>                                                 api->send(eid,message);
> 
> }
> 
> receiver Thread:
> 
>         api_thread_t *api = api_thread_t::create (&_dispatch, &_locator);
>        api->create_queue ("Q",scope_process);
>     while(1){
>                         message_t message;
>                         api->receive (&message);
> 
> }
> 
> 
> 
> everything compiles and I receive my feed and send it on, but I never 
> receive any messages on the Receiver side of the queue.  Any thoughts?
> 
> -Todd
> 
> 
> On Thu, Apr 9, 2009 at 3:19 AM, Martin Sustrik <sustrik at fastmq.com 
> <mailto:sustrik at fastmq.com>> wrote:
> 
>     Hi Todd,
> 
> 
>         I am just getting started with 0mq and I would like some advice.
> 
>         I have an application which basically combines N streaming feeds
>         of information and outputs a single combined feed of
>         information.  My application has a thread for each feed and an
>         output thread with a queue that I implemented that is shared
>         among the threads.  After reading your design docs, I feel your
>         messaging implementation will probably perform better.  My
>         question lies in the local_scope verses process_scope.  Should
>         each feed have a local scope exchange connected to a process
>         scope queue?  If so how would I bind the queue to the exchange
>         on the consuming side?
> 
> 
>     This is a nice little use case for in-process messaging.
> 
>     1. Open a locator. There are no components running on the network so
>     you can do without a zmq_server. Pass NULL instead of zmq_server
>     address:
> 
>     locator_t locator (NULL);
> 
>     2. Open a dispatcher. Say you have 3 sender threads and a single
>     receiver thread. Initialise dispatcher to have 4 threads:
> 
>     dispatcher_t dispatcher (4);
> 
>     3. Create an api_thread_t object in each thread:
> 
>     api_thread_t *api = api_thread_t::create (&dispatcher, &locator);
> 
>     API thread gives you the interface to 0MQ functionaity. Note that an
>     instance of api_thread_t MUST be used from just a single thread.
> 
>     4. In receiver thread create a process-wide queue. Making it
>     process-scoped means that other threads will be able to see it and
>     bind to it:
> 
>     api->create_queue ("Q", scope_process);
> 
>     5. In each sender thread create a local exchange (nobody needs to
>     bind to it except the thread that created it) and bind it to the
>     queue created by receiver thread:
> 
>     int eid = api->create_exchange ("E", scope_local);
>     api->bind ("E","Q");
> 
>     6. Now you are able to send messages from sender threads:
> 
>     message_t msg (10);
>     ...
>     api->send (eid, msg);
> 
>     7. In receiver thread, you can receive the messages:
> 
>     message_t msg;
>     api->receive (&msg);
> 
>     Some additional comments:
> 
>     If you are striving for extra-high performance - and if your
>     messages have non-negligible length - you should take overhead
>     intoduced by copying the message into account.
> 
>     0MQ provides you with two ways to create a message to send:
> 
>     message_t msg (100);
> 
>     Creates a message with 100 byte buffer for you. It is optimised for
>     performance. If the message small it allocates the buffer on the
>     stack, if it's larger, it allocates it on the heap, however, it
>     allocates a single chunk for both message data and metadata.
> 
>     The other way to create a message should be used when the message is
>     handed to you that's already allocated and you have no way to
>     control it's creation (mostly with legacy applications):
> 
>     message_t msg (data, size, free);
> 
>     Third parameter is pointer to the function to use to deallocate the
>     data.
> 
>     If what you need is a extremely high performance on a multicore box,
>     you should also consider using optimised memory allocation mechanism
>     (like tcmalloc) instead of the raw malloc.
> 
>     Let us know what kind of performance improvement you've achieved
>     using 0MQ!
> 
>     Martin
> 
> 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.cpp
Type: text/x-c++src
Size: 1378 bytes
Desc: not available
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20090409/025c54e5/attachment.cpp>


More information about the zeromq-dev mailing list